Last active
August 29, 2015 14:02
-
-
Save congjf/0491190cdce6562fc71d to your computer and use it in GitHub Desktop.
Swift 语言基础
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Swift 语言基础 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ============================== | |
// 前沿 & 注释 | |
// ============================== | |
/* 本篇文章来自苹果官方的Swift文档 | |
The Swfit Programming Language */ | |
/* | |
/* 我根据文档以及个人的理解,对部分代码进行了注释。 */ | |
/* 文章中的代码,是文档中第一章的全部源码,以及部分 */ | |
/* 后续章节的代码,我会根据自己的学习进度,不断的对 */ | |
/* 文章进行更新。——道禅僧 */ | |
/* */ | |
/* 文章原始链接: */ | |
/* https://gist.github.com/congjf/0491190cdce6562fc71d | |
/* */ | |
*/ To Be Continue... */ | |
// ============================== | |
// Hello world | |
// ============================== | |
println("Hello World!") | |
// ============================== | |
// 常量、变量定义 | |
// ============================== | |
var myVaribale = 42 | |
myVaribale = 50 | |
let myConstant = 42 | |
// ============================== | |
// 初始化常量/变量类型 | |
// ============================== | |
let implicitInteger = 70 | |
let implicitDouble = 70.0 | |
// 冒号表示“...是...类型” | |
let explicitDouble: Double = 70 | |
// ============================== | |
let minValue = UInt8.min // 0 | |
let maxValue = UInt8.max // 255 | |
// ============================== | |
let decimalInteger = 17 | |
let binaryInteger = 0o21 | |
let hexadecimalInter = 0x11 | |
let decimalDouble = 12.1875 | |
let exponentDouble = 1.21875e1 | |
let hexadecimalDouble = 0xC.3p0 | |
let paddedDouble = 000123.456 | |
let oneMillion = 1_000_000 | |
let justOverOneMillion = 1_000_000.000_000_1 | |
// ============================== | |
// 强制类型转换 | |
// ============================== | |
let label = "The width is " | |
let width = 94 | |
let widthLabel = label + String(width) | |
// ============================== | |
let three = 3 | |
let pointOneFourOneFiveNine = 0.14159 | |
let pi = Double(three) + pointOneFourOneFiveNine | |
// ============================== | |
// 类型别名 | |
// ============================== | |
typealias AudioSample = UInt16 | |
var maxAmplitudeFound = AudioSample.min | |
// ============================== | |
// 字符串拼接 | |
// ============================== | |
let apples = 3 | |
let oranges = 5 | |
let appleSummary = "I have \(apples) apples." | |
let fruitSummary = "I have \(apples + oranges) pieces of fruit." | |
// ============================== | |
// 数组、字典 | |
// ============================== | |
var shoppingList = ["catfish", "water", "tulips", "blue paint"] | |
shoppingList[1] = "bottle of water" | |
var occupations = [ | |
"Malcolm": "Captain", | |
"Kaylee": "Mechanic", | |
] | |
occupations["Jayne"] = "Public Relations" | |
// ============================== | |
// 元组 | |
// ============================== | |
// http404Error 是一个 (Int, String) 类型的元组 | |
let http404Error = (404, "Not Found") | |
let (statusCode, statusMessage) = http404Error | |
statusCode | |
statusMessage | |
http404Error.1 | |
// ============================== | |
let http200Status = (statusCode: 200, description: "OK") | |
http200Status.statusCode | |
// ============================== | |
// 空数组、空字典 | |
// ============================== | |
let emptyArray = String[]() | |
let emptyDictionary = Dictionary<String, Float>() | |
// ============================== | |
// 控制语句 | |
// ============================== | |
let individualScores = [75, 43, 103, 87, 12] | |
var teamScore = 0 | |
for score in individualScores { | |
// if 语句只能接受布尔表达式 | |
if score > 50 { | |
teamScore += 3 | |
} else { | |
teamScore += 1 | |
} | |
} | |
teamScore | |
// ============================== | |
// 可选值 | |
// ============================== | |
/* 当一个对象的值可能是“不存在”的时候, | |
你可以使用“可选”操作符来标示一个对象。 | |
有值,并且这个值是... | |
根本就没有值! | |
*/ | |
let possibleNumber = "123" | |
let convertedNumber = possibleNumber.toInt() | |
println(convertedNumber!) | |
if convertedNumber { | |
println("\(possibleNumber) has an integer value of \(convertedNumber!)") | |
} else { | |
println("\(possibleNumber) could not be converted to an integer") | |
} | |
// ============================== | |
// 可以一起使用 if 与 let 来防止在 if 语句中出现值丢失的问题 | |
// 可选值可以是一个 值 也可以是 nil ,来表示值是否存在 | |
// 声明变量时,加入 ? 符号来表示这个对象的值是 可选 的 | |
var optionalString: String? = "Hello" | |
optionalString == nil | |
// 如果optionalName的值是 nil ,则 if 语句的判断结果是 否 | |
var optionalName: String? = "John Appleseed" | |
var greeting = "Hello!" | |
if let name = optionalName { | |
greeting = "Hello, \(name)" | |
} | |
// ============================== | |
// switch语句 | |
// ============================== | |
let vegetable = "red pepper" | |
switch vegetable { | |
case "celery": | |
let vegetableComment = "Add some raisins and make ants on a log." | |
case "cucumber", "watercress": | |
let vegetableComment = "That would make a good tea sandwich." | |
case let x where x.hasSuffix("pepper"): | |
let vegetableComment = "Is it a spicy \(x)?" | |
default: | |
let vegetableComment = "Everything tastes good in soup." | |
} | |
// 注意:这里没有用 break 语句,因为当分支运行完后,会跳出 switch 语句 | |
// ============================== | |
// for-in | |
// ============================== | |
let interestingNumbers = [ | |
"Prime": [2, 3, 5, 7, 11, 13], | |
"Fibonacci": [1, 1, 2, 3, 5, 8], | |
"Square": [1, 4, 9, 16, 25], | |
] | |
var largest = 0 | |
for (kind, numbers) in interestingNumbers { | |
for number in numbers { | |
if number > largest { | |
largest = number | |
} | |
} | |
} | |
largest | |
// ============================== | |
// while | |
// ============================== | |
var n = 2 | |
while n < 100 { | |
n = n * 2 | |
} | |
n | |
var m = 2 | |
do { | |
m = m * 2 | |
} while m < 100 | |
m | |
// ============================== | |
// 自动序列 | |
// ============================== | |
var firstForLoop = 0 | |
for i in 0..3 { | |
firstForLoop += i | |
} | |
firstForLoop | |
var secondForLoop = 0 | |
for var i = 0; i < 3; ++i { | |
secondForLoop += 1 | |
} | |
secondForLoop | |
// ============================== | |
// 方法定义 | |
// ============================== | |
// 使用 -> 标识返回值类型 | |
// 使用 : 标识传入值类型 | |
func greet(name: String, day: String) -> String { | |
return "Hello \(name), today is \(day)." | |
} | |
greet("Bob", "Tuesday") | |
// ============================== | |
// 多返回值 | |
// ============================== | |
func getGasPrices() -> (Double, Double, Double) { | |
return (3.59, 3.69, 3.79) | |
} | |
getGasPrices() | |
// ============================== | |
// 不确定个数的输入 | |
// ============================== | |
func sumOf(numbers: Int...) -> Int { | |
var sum = 0 | |
for number in numbers { | |
sum += number | |
} | |
return sum | |
} | |
sumOf() | |
sumOf(42, 597, 12) | |
// ============================== | |
// 内嵌方法 | |
// ============================== | |
func returnFifteen() -> Int { | |
var y = 10 | |
// 内嵌方法可以调用外层方法的对象 | |
func add() { | |
y += 5 | |
} | |
add() | |
return y | |
} | |
returnFifteen() | |
// ============================== | |
// 函数作为返回 | |
// ============================== | |
// 函数是一等公民,所以可以将函数当做 返回值 来用 | |
func makeIncrementer() -> (Int -> Int) { | |
func addOne(number: Int) -> Int { | |
return 1 + number | |
} | |
return addOne | |
} | |
var increment = makeIncrementer() | |
increment(7) | |
// ============================== | |
// 函数作为输入值 | |
// ============================== | |
func hasAnyMatches(list: Int[], condition: Int -> Bool) -> Bool { | |
for item in list { | |
if condition(item) { | |
return true | |
} | |
} | |
return false | |
} | |
func lessThanTen(number: Int) -> Bool { | |
return number < 10 | |
} | |
var numbers = [20, 19, 7, 12] | |
hasAnyMatches(numbers, lessThanTen) | |
// ============================== | |
// 闭包 | |
// ============================== | |
numbers.map({ | |
// 使用 in 来区分返回值类型与方法体 | |
(number: Int) -> Int in | |
let result = 3 * number | |
return result | |
}) | |
// ============================== | |
// 简写闭包 | |
// ============================== | |
// 输入 number ,返回 3*number | |
numbers.map({ number in 3*number }) | |
// 先输入 0 和 1 ,然后输入 0 和 1 的比较结果和 5 ,依此类推 | |
sort([0, 1, 5, 3, 2]) { $0 < $1 } | |
// ============================== | |
// 类定义 | |
// ============================== | |
class Shape { | |
var numberOfSides = 0 // 属性定义 | |
func simpleDescription() -> String { // 成员方法 | |
return "A shape with \(numberOfSides) sides." | |
} | |
} | |
// ============================== | |
// 实例化 | |
// ============================== | |
var shape = Shape() // Shape 是一个类 | |
shape.numberOfSides = 7 // 获取成员属性 | |
var shapeDescription = shape.simpleDescription() // 调用成员方法 | |
// ============================== | |
// 构造函数 | |
// ============================== | |
class NamedShape { | |
var numberOfSides: Int = 0 | |
var name: String | |
// init 函数为构造函数,deinit 函数为析构函数 | |
init(name: String) { | |
self.name = name // seft 标识类属性 | |
} | |
func simpleDescription() -> String { | |
return "A shape with \(numberOfSides) sides." | |
} | |
} | |
// ============================== | |
// 继承 | |
// ============================== | |
class Square: NamedShape { | |
var sideLength: Double | |
init(sideLength: Double, name: String) { | |
self.sideLength = sideLength | |
super.init(name: name) | |
numberOfSides = 4 | |
} | |
func area() -> Double { | |
return sideLength * sideLength | |
} | |
// 重写 | |
override func simpleDescription() -> String { | |
return "A square with sides of length \(sideLength)." | |
} | |
} | |
let test = Square(sideLength: 5.2, name: "my test square") | |
test.area() | |
test.simpleDescription() | |
// ============================== | |
// Setter 与 Getter | |
// ============================== | |
class EquilateralTriangle: NamedShape { | |
var sideLength: Double = 0.0 | |
init(sideLength: Double, name: String) { | |
self.sideLength = sideLength | |
super.init(name: name) | |
numberOfSides = 3 | |
} | |
var perimeter: Double { | |
get { | |
return 3.0 * sideLength | |
} | |
set { | |
sideLength = newValue / 3.0 | |
} | |
} | |
override func simpleDescription() -> String { | |
return "An equilateral triagle with sides of length \(sideLength)." | |
} | |
} | |
var triangle = EquilateralTriangle(sideLength: 3.1, name: "a triangle") | |
triangle.perimeter | |
triangle.perimeter = 9.9 | |
triangle.sideLength | |
// ============================== | |
class TriangleAndSquare { | |
var triangle: EquilateralTriangle { | |
// 属性赋值后执行 | |
willSet { | |
square.sideLength = newValue.sideLength | |
} | |
} | |
var square: Square { | |
// 属性赋值后执行 | |
willSet { | |
triangle.sideLength = newValue.sideLength | |
} | |
} | |
init(size: Double, name: String) { | |
square = Square(sideLength: size, name: name) | |
triangle = EquilateralTriangle(sideLength: size, name: name) | |
} | |
} | |
var triangleAndSquare = TriangleAndSquare(size: 10, name: "another test shape") | |
triangleAndSquare.square.sideLength | |
triangleAndSquare.triangle.sideLength | |
triangleAndSquare.square = Square(sideLength: 50, name: "larger square") | |
triangleAndSquare.triangle.sideLength | |
// ============================== | |
// Method 和 Function | |
// ============================== | |
// Method 是类成员方法 | |
// Function 是类外的函数 | |
// Function与Method有一个重要的区别, | |
// Function的输入参数名只能用在Function内部, | |
// Mehthod的输入参数名可以用在调用这个Method的时候 | |
class Counter { | |
var count: Int = 0 | |
// times 是 numberOfTimes 在函数内的别名 | |
func incrementBy(amount: Int, numberOfTimes times: Int) { | |
count += amount * times | |
} | |
} | |
var counter = Counter() | |
counter.incrementBy(2, numberOfTimes: 7) | |
// ============================== | |
// “可选”操作符 | |
// ============================== | |
// 当使用 可选值对象 时,你可以在操作符的前面写 ? , | |
// 如果在 ? 之前的值是 nil, 忽略在 ?后的所有内容,并且整个表达式的内容都是 nil , | |
// Otherwise, the optional value is unwrapped, and everything after the ? acts on the unwrapped value. | |
// In both cases, the value of the whole expression is an optional value. | |
let optionalSquare: Square? = Square(sideLength: 2.5, name: "optional square") | |
let sideLength = optionalSquare?.sideLength | |
// ============================== | |
// 枚举类型和结构体 | |
// ============================== | |
enum Rank: Int { | |
case Ace = 1 | |
case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten | |
case Jack, Queen, King | |
func simpleDescription() -> String { | |
switch self { | |
case .Ace: | |
return "ace" | |
case .Jack: | |
return "jack" | |
case .Queen: | |
return "queen" | |
case .King: | |
return "king" | |
default: | |
return String(self.toRaw()) | |
} | |
} | |
} | |
let ace = Rank.Queen | |
let aceRawValue = ace.toRaw() | |
let aceDesciption = ace.simpleDescription() | |
// ============================== | |
// 注意 .fromRaw 方法与 .toRaw 方法 | |
if let convertedRank = Rank.fromRaw(2){ | |
let threeDescription = convertedRank.simpleDescription() | |
} | |
// ============================== | |
enum Suit { | |
case Spades, Hearts, Diamonds, Clubs | |
func simpleDescription() -> String { | |
switch self { | |
case .Spades: | |
return "spades" | |
case .Hearts: | |
return "hearts" | |
case .Diamonds: | |
return "diamonds" | |
case .Clubs: | |
return "clubs" | |
} | |
} | |
} | |
let hearts = Suit.Hearts | |
let heartsDescription = hearts.simpleDescription() | |
// ============================== | |
enum ServerResponse { | |
case Result(String, String) | |
case Error(String) | |
} | |
let success = ServerResponse.Result("6:00 am", "8:09 pm") | |
let failure = ServerResponse.Error("Out of cheese.") | |
switch success { | |
case let .Result(sunrise, sunset): | |
let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)." | |
case let .Error(error): | |
let serverResponse = "Failure... \(error)" | |
} | |
// ============================== | |
// 结构体 | |
// ============================== | |
struct Card { | |
var rank: Rank | |
var suit: Suit | |
func simpleDescription() -> String { | |
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" | |
} | |
} | |
let threeOfSpades = Card(rank: .Three, suit: .Spades) | |
let threeOfSpadesDescription = threeOfSpades.simpleDescription() | |
// ============================== | |
// 协议与扩展 | |
// ============================== | |
// 协议类似其他语言中的接口 | |
protocol ExampleProtocol { | |
var simpleDescription: String { get } | |
mutating func adjust() | |
} | |
// ============================== | |
class SimpleClass: ExampleProtocol { | |
var simpleDescription: String = "A very simple class." | |
var anotherProperty: Int = 69105 | |
func adjust() { | |
simpleDescription += " Now 100% adjusted." | |
} | |
} | |
var a = SimpleClass() | |
a.adjust() | |
let aDescription = a.simpleDescription | |
struct SimpleStructure: ExampleProtocol { | |
var simpleDescription: String = "A simple structure" | |
// 使用 mutating 关键字标明这个方法改变了这个结构体 | |
mutating func adjust() { | |
simpleDescription += " (adjusted)" | |
} | |
} | |
var b = SimpleStructure() | |
b.adjust() | |
let bDescription = b.simpleDescription | |
// ============================= | |
// 使用扩展为一个类添加新的方法 | |
extension Int: ExampleProtocol { | |
var simpleDescription: String { | |
return "The number \(self)" | |
} | |
mutating func adjust() { | |
self += 42 | |
} | |
} | |
7.simpleDescription | |
//=============================== | |
// 注意:动态类型指定、匹配 | |
let protocolValue: ExampleProtocol = a | |
protocolValue.simpleDescription | |
// protocolValue.anotherProperty // Uncomment to see the error | |
// ============================== | |
// 泛型 | |
// (Generics) | |
// ============================== | |
func repeat<ItemType>(item: ItemType, times: Int) -> ItemType[] { | |
var result = ItemType[]() | |
for i in 0..times { | |
result += item | |
} | |
return result | |
} | |
repeat("knock", 4) | |
repeat(1, 4) | |
// ============================== | |
// Reimplement the Swift standard library's optional type | |
enum OptionalValue<T> { | |
case None | |
case Some(T) | |
} | |
var possibleInteger: OptionalValue<Int> = .None | |
possibleInteger = .Some(100) | |
// ============================== | |
// 在类型名后面使用 where 关键字,来指定一个请求列表, | |
// 比如:请求实现一个协议的类型 | |
func anyCommonElements <T, U | |
where | |
T: Sequence, U: Sequence, | |
T.GeneratorType.Element: Equatable, | |
T.GeneratorType.Element == U.GeneratorType.Element> | |
(lhs: T, rhs: U) -> Bool { | |
for lhsItem in lhs { | |
for rhsItem in rhs { | |
if lhsItem == rhsItem { | |
return true | |
} | |
} | |
} | |
return false | |
} | |
anyCommonElements([1, 2, 3], [3]) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment