一邊學習Swift,一邊寫筆記,相信在有一定其他語言基礎的情況下用1.5小時看完該文章即可掌握。然後再花30分鐘打開XCode寫個Demo. 生命中拿出2小時來認識一門語言,很值吧!
筆記共分為兩部分,一Swift基礎知識,二使用Xcode開發一個軟件
[TOC]
//定義變量
var myVariable = 123
//定義常量
let myConstantVariable = 123
// 隱式指定整數類型
var anInteger = 2
// 明確指定整數類型
let anExplicitInteger :Int = 2
let aTuple = (1, "Yes")
let anotherTuple = (aNumber: 1, aString: "Yes")
let theOtherNumber = anotherTuple.aNumber // = 1
其他用法
let http404Error = (404, "Not Found")
let (statusCode, statusMessage) = http404Error
print("The status code is \(statusCode)")
更多用戶函數返回值,返回兩個以上的值,跟golang很像
var arrayOfIntegers : [Int] = [1,2,3]
// 隱式指定
var implicitArrayOfIntegers = [1,2,3]
// 也可以創建空數組,但必須提供其類型
let anotherArray = [Int]()
//使用 append 函數向數組的末尾追加對象
myArray.append(4)
//數組中的任意位置插入對象
myArray.insert(5, atIndex: 0)
字典是一種將鍵映射到值的類型,類似Java的Map,PHP的數組
var crew = [
"Caption": "Jean-Luc Picard",
"First officer": "William Riker",
"Second Officer": "Data"
];
crew["Captain"]
// = "Jean-Luc Picard"
if 1+1 == 2 {
println("The math checks out")
}
let loopingArray = [1,2,3,4,5]
var loopSum = 0
for number in loopingArray {
loopSum += number
}
loopSum // = 15
var firstCounter = 0
for index in 1 ..< 10 {
firstCounter++
}
// 循環9次
var secondCounter = 0
for index in 1 ... 10 { // 注意是三個句點,不是兩個
secondCounter++
}
// 循環10次
var sum = 0
for var i = 0; i < 3; i++ {
sum += 1
}
sum // = 3
var countDown = 5
while countDown > 0 {
countDown--
}
countDown // = 0
var countUP = 0
do {
countUp++
} while countUp < 5
countUp // = 5
可以用 if-let 語句檢查一個可選變量是否包 含值。如果包含,則將這個值指定給一個常量變量,然後運行某段代碼。這樣可以減少很 多行代碼,同時又能夠保證安全性
var conditionalString : String? = "a string"
if let theString = conditionalString? {
println("The string is '\(theString)'")
} else {
println("The string is nil")
}
// 輸出 "The string is 'a string'"
兩個參數一個返回值,都為Int
func thirdFunction(firstValue: Int, secondValue: Int) -> Int {
return firstValue + secondValue
}
thirdFunction(1, 2)
func fourthFunction(firstValue: Int, secondValue: Int)
-> (doubled: Int, quadrupled: Int) {
return (firstValue * 2, secondValue * 4)
}
fourthFunction(2, 4)
// 用數字訪問:
fourthFunction(2, 4).1 // = 16
// 其他相同,只是使用了名字:
fourthFunction(2, 4).quadrupled // = 16
在定義函數時,可以為參數指定名字。當無法馬上明白每個參數的用途時,這一功能會非 常有用。可以像下面這樣來定義參數名字:
func addNumbers(firstNumber num1 : Int, toSecondNumber num2: Int) -> Int {
return num1 + num2
}
addNumbers(firstNumber: 2, toSecondNumber: 3) // = 5
在為參數創建名字時,就是為參數創建一個內部名字和一個外部名字,一個參數的內部名字應當與外部名字相同。將同一個名字輸 入兩次也沒有什麼問題,但的確有一種簡便的方式來定義一個外部名字與內部名字相同的 參數——就是在參數名之前放一個 # 符號
func multiplyNumbers(#firstNumber: Int, #multiplier: Int) -> Int {
return firstNumber * multiplier
}
multiplyNumbers(firstNumber: 2, multiplier: 3) // = 6
var numbersFunc: (Int, Int) -> Int;
// numbersFunc現在可以存儲任何接受兩個Int並返回一個Int的函數
numbersFunc = addNumbers
numbersFunc(2, 3) // = 5
sort需要傳遞一個閉包作為參數
var numbers = [2,4,34,6,33,1,67,20]
var numbersSorted = numbers.sort( { (first, second ) -> Bool in
return first < second
})
閉包只包含一行代碼,可以省略 return 關鍵字
var numbersSorted = numbers.sort( { $1 > $0})
print(numbersSorted)
如果一個閉包是函數調用中的最後一個參數,可以將它放在括號外面。這純粹是為 了提高可讀性,不會改變閉包的工作方式
var numbersSorted = numbers.sort(){ $1 > $0}
print(numbersSorted)
閉包放在變量裡面
var comparator = {(a: Int, b: Int) in a < b}
comparator(1, 2) // = true
class Vehicle {
var color: String?
var maxSpeed = 80
func description() -> String {
return "A \(self.color) vehicle"
}
func travel() {
print("Traveling at \(maxSpeed) kph")
}
}
var redVehicle = Vehicle()
redVehicle.color = "Red"
redVehicle.maxSpeed = 90
redVehicle.travel() // 輸出"Traveling at 90 kph" redVehicle.description() // = "A Red vehicle"
要重寫一個函數,要在子類中重新聲明它,並添加 override 關鍵字
class Car: Vehicle {
// 繼承類可以重寫函數
override func description() -> String {
var description = super.description()
return description + ", which is a car"
} }
在一個被重寫的函數中,可以通過 super 回調該函數在父類中的版本
override func description() -> String {
var description = super.description()
return description + ", which is a car"
}
class InitAndDeinitExample {
// 指定的初始化器(也就是主初始化器)
init() {
print("I've been created!")
}
// 便捷初始化器,是調用上述指定初始化器所必需的
convenience init (text: String) {
self.init() // 這是必需的
print("I was called with the convenience initializer!")
}
// 反初始化器
deinit {
print("I'm going away!")
}
}
var example : InitAndDeinitExample?
// 使用指定的初始化器
example = InitAndDeinitExample() // 輸出"I've been created!"
example = nil // 輸出"I'm going away"
// 使用便捷初始化器
example = InitAndDeinitExample(text: "Hello")
// 輸出"I've been created!"
// 然後輸出"I was called with the convenience initializer"
創建一個可以返回 nil 的初始化器(也稱為可以失敗的初始化器),就在 init 關鍵字的後面放上一個問號,並在初始化器確定它不能成功地構造該對象時,使用 return nil:
convenience init? (value: Int) {
self.init()
if value > 5 {
// 不能初始化這個對象;返回nil,表示初始化失敗 return nil
} }
在使用一個可以失敗的初始化器時,任何可以在其中存儲該結果的變量都是可選的:
let failableExample = InitAndDeinitExample(value: 6)
// = nil
使用協議的好處是,可以利用 Swift 的類型體系來引用任何遵守某一給定協議的對象,個人現在理解為是Interface概念。
protocol Blinking{
var isBlinking:Bool{get}
var blinkSpeed: Double { get set }
func startBlinking(blinkSpeed: Double) -> Void
}
class Light:Blinking{
var isBlinking = false
var blinkSpeed = 1.2
func startBlinking(blinkSpeed: Double) {
print("now my speed is \(self.blinkSpeed)")
}
}
extension Int {
var doubled : Int {
return self * 2
}
func multiplyWith(anotherNumber: Int) -> Int {
return self * anotherNumber
} }
2.doubled // = 4
4.multiplyWith(32) // = 128
還可以利用擴展使一個類型遵守一個協議
extension Int : Blinking {
var isBlinking : Bool {
return false;
}
var blinkSpeed : Double {
get {
return 0.0; }
set {
// 不做任何事情
} }
func startBlinking(blinkSpeed : Double) {
print("I am the integer \(self). I do not blink.")
} }
2.isBlinking // = false
2.startBlinking(2.0) // 輸出"I am the integer 2. I do not blink."
在將一個方法或屬性聲明為 public 時,App 中的所有人都能看到它:
// 可供所有人訪問
public var publicProperty = 123
//如果將一個方法或屬性聲明為 private,那只能在聲明它的源文件內部看到它:
// 只能在這個源文件中訪問
private var privateProperty = 123
// 僅能供本模塊訪問
// 這裡的'internal'是默認的,可以省略
internal var internalProperty = 123
類似C++的運算符重載
class Vector2D {
var x : Float = 0.0
var y : Float = 0.0
init (x : Float, y: Float) {
self.x = x
self.y = y
}
}
func +(left : Vector2D, right: Vector2D) -> Vector2D {
let result = Vector2D(x: left.x + right.x, y: left.y + right.y)
return result
}
let first = Vector2D(x: 2, y: 2)
let second = Vector2D(x: 4, y: 1)
let result = first + second
Swift與Java泛型相同
class Tree <T> {
// 'T'現在可以用作一種類型 var value : T
var value:T
var children : [Tree <T>] = []
init(value : T) {
self.value = value
}
func addChild(value : T) -> Tree <T> {
var newChild = Tree<T>(value: value)
children.append(newChild)
reutrn newChild
}
}
// 整數樹
let integerTree = Tree<Int>(value: 5)
// 可以增加包含Int的子樹
integerTree.addChild(10)
//用Swift設計程序 | 45
integerTree.addChild(5)
// 字符串樹
let stringTree = Tree<String>(value: "Hello")
stringTree.addChild("Yes")
stringTree.addChild("Internets")
比較字符串
let string1 : String = "Hello"
let string2 : String = "Hel" + "lo"
if string1 == string2 {
println("The strings are equal")
}
查找字符串
if string1.hasPrefix("H") {
println("String begins with an H")
}
if string1.hasSuffix("llo") {
println("String ends in 'llo'")
}
let stringToConvert = "Hello, Swift"
let data = stringToConvert.dataUsingEncoding(NSUTF8StringEncoding)
打開Xcode 7.2
打開Xcode新建Project選擇OSX Application


打開Main.storyboard,在ViewController中拖入Label

修改ViewController.swift代碼
import Cocoa
class ViewController: NSViewController {
@IBOutlet weak var timestamp:NSTextField!
@IBOutlet weak var dateLabel:NSTextField!
@IBAction func calc(sender:NSButton){
//將輸入的字符串轉為NSString
let string = NSString(string: self.timestamp.stringValue)
//轉為double類型
let ts:NSTimeInterval = string.doubleValue
//轉換日期
let date = NSDate(timeIntervalSince1970: ts)
//日期格式化
let dfmatter = NSDateFormatter()
dfmatter.dateFormat="yyyy年MM月dd日"
//顯示到Label
dateLabel.stringValue = dfmatter.stringFromDate(date)
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override var representedObject: AnyObject? {
didSet {
// Update the view, if already loaded.
}
}
}
上述的NSTextField後面的歎號,它被稱為隱式拆封的可選類型,是一種特殊類型,指出變量可能有值,也可能為nil。Swift運行 環境不喜歡訪問值為nil的變量,因此Swift程序員必須知曉變量的值,尤其在其可能為nil時。
將變量聲明為隱式拆封的可選類型相當於告訴Swift編譯器,你承諾在該變量的值為nil時絕 不會訪問它。這是你與編譯器簽訂的一個合約,你必須遵守。如果你不遵守,在變量為nil時訪 問它,將引發運行階段錯誤,導致應用程序停止運行
另外也可以開啟兩個視圖直接拖入例如:

鏈接UI與代碼部分,將TextField右鍵,選擇new referencing Outlets點加號指向ViewController,在彈出的選項裡面選擇timestamp,同樣方式選擇到label上。

綁定按鈕的click事件

點擊上方的三角箭頭運行程序
Ubuntu 15.10安裝部署Swift開發環境 http://www.linuxidc.com/Linux/2016-01/126995.htm
Swift 的變化:從 2.2 到 3.0 會帶來什麼 http://www.linuxidc.com/Linux/2015-12/126440.htm
Swift 正式開源,同時開源 Swfit 核心庫和包管理器 http://www.linuxidc.com/Linux/2015-12/125847.htm
Apple Swift學習教程 http://www.linuxidc.com/Linux/2014-09/106420.htm
使用 Swift 構建一個 iOS 的郵件應用 http://www.linuxidc.com/Linux/2014-08/105542.htm
Swift 2.0開源化 http://www.linuxidc.com/Linux/2015-06/118594.htm
Linux下搭建Swift語言開發學習環境 http://www.linuxidc.com/Linux/2015-12/125983.htm
Swift 的詳細介紹:請點這裡