以下關鍵字關於引用傳參、屬性、修改成員變量、靜態變量、索引和構造函數重載
讀過The Swift Programming Language的人都能看得出,我上面的這幾個說法全不是apple的習慣用語。之所以這么起題目是因為很多最近轉到swift下,但原本又不是搞ios開發的人,並不習慣apple的說法。他們經常在查詢他人博客的時候因為某些名詞的表示方式不同,而把原本簡單的問題搞得一頭霧水。就像我在剛接觸oc的時候,很奇怪message和protocol的說法一樣,因為我的mother programming language可以說是C#,我更接受parameter和interface的說法。
下面讓我們用幾個簡單的keyword來解釋一下swift中這幾個可能會讓你想幾分鍾,但本身又很簡單的語法。
一、 in-out
這里in-out作為函數聲明時,引用傳值的關鍵字。相當於C#和Java中得ref和out。但是在函數調用的時候要寫一個“&”符號在參數前面。
如下列代碼:
func swapTwoInts(inout a: Int, inout b: Int) { let temporaryA = a a = b b = temporaryA } var someInt = 3 var anotherInt = 107 swapTwoInts(&someInt, &anotherInt) println("someInt is now \(someInt), and anotherInt is now \(anotherInt)")
這是The Swift Programming Language中的實例,交換兩個數的值。
二、 get set and willSet didSet
對於C#熟悉的人可以一眼看出get set是什么意思,就如下面代碼所示,這種寫法可以簡化我們的工作:
struct AlternativeRect { var origin = Point() var size = Size() var center: Point { get { let centerX = origin.x + (size.width / 2) let centerY = origin.y + (size.height / 2) return Point(x: centerX, y: centerY) } set { origin.x = newValue.x - (size.width / 2) origin.y = newValue.y - (size.height / 2) } } }
對於更簡單而言我們還有@lazy的寫法,用於屬性在初始化之后才被賦值的情況。
class Head{
var eyes = "eyes"
var nose = "Nose"
}
class Arm{
var hands = "hands"
}
class Human{
@lazy var head = Head()
@lazy var arm = Arm()
}
var human = Human()
var newhead = Head()
newhead.eyes = "blueeyes"
human.head = newhead
如果是protocol中聲明一個屬性,可以:
protocol SomeProtocol { var mustBeSettable: Int { get set } var doesNotNeedToBeSettable: Int { get } }
其實這也比較像C#,以前的oc是不支持protocol中有屬性的,僅僅是個方法列表。
willSet和didSet是兩個非常好玩的東西。可以對屬性賦值前和賦值后進行一定的操作:
class StepCounter { var totalSteps: Int = 0 { willSet(newTotalSteps) { println("About to set totalSteps to \(newTotalSteps)") } didSet { if totalSteps > oldValue { println("Added \(totalSteps - oldValue) steps") } } } } let stepCounter = StepCounter() stepCounter.totalSteps = 200 // About to set totalSteps to 200 // Added 200 steps stepCounter.totalSteps = 360 // About to set totalSteps to 360 // Added 160 steps stepCounter.totalSteps = 896 // About to set totalSteps to 896 // Added 536 steps
這種方法對於寫一個客戶端app增加了極大的靈活性,把willSet和didSet封裝到class中有助於我們更方便的控制對象的屬性。
三、 mutating
這個關鍵字至少我是第一次見,他的作用是寫在func前面,以便讓func可以修改struct和protocol的extension中的成員的值。如果不加此關鍵字,成員值便被保護起來,不得修改。
例如:
struct Point { var x = 0.0, y = 0.0 mutating func moveByX(deltaX: Double, y deltaY: Double) { x += deltaX y += deltaY } } var somePoint = Point(x: 1.0, y: 1.0) somePoint.moveByX(2.0, y: 3.0) println("The point is now at (\(somePoint.x), \(somePoint.y))")
這讓成員事實上面的更加的安全,因為在swift中沒有private的概念。
四、 class var
在swift中對於enum和struct來說支持用static關鍵字來標示靜態變量,但是對於class成員來說,只能以class var的方式返回一個只讀值。如下:
struct SomeStructure { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { // return an Int value here } } enum SomeEnumeration { static var storedTypeProperty = "Some value." static var computedTypeProperty: Int { // return an Int value here } } class SomeClass { class var computedTypeProperty: Int { // return an Int value here } }
這樣其實很好的區分了struct和class的功能,不像C#抓來一個隨便用,但相對於oc來講其實是弱化了界限,如果你想在class中搞一個非只讀的靜態變量出來,可以和struct進行配合。
若想實現安全線程的單例模式,可以采用和struct結合的方式:
來源:http://blog.csdn.net/u010124617/article/details/28856711
class SwiftSingleton{ class func shareInstance()->SwiftSingleton{ struct YRSingleton{ static var predicate:dispatch_once_t = 0 static var instance:SwiftSingleton? = nil } dispatch_once(&YRSingleton.predicate,{ YRSingleton.instance=SwiftSingleton() } ) return YRSingleton.instance! } }
五、 subscript syntax
所謂subscript就是用[]來進行索引,這種語法十分靈活,可能借鑒了一些Python的風格。
如struct、array、dictionary都可以通過subscript進行索引:
struct Duden { let offset:Int var textCount:Int subscript(index:Int) -> Int{ get{ return index - offset } set(newvalue){ textCount = newvalue * 3 } } } var duden = Duden(offset:2,textCount:0) duden[9] //7
duden[9] = 8 //duden.textCount 24
六、 convenience
convenience用來進行方便的初始化,說白了就相當於構造函數重載,對於class來講,默認或指定的初始化方法作為所謂的Designated初始化,若重載的初始化需要調用Designated初始化則將它作為convenience初始化,在方法前要加上convenience關鍵字。
class Figure{ var name:String! var nikname:String? init(){ name = "John" } convenience init(name:String!,nikname:String!){ self.init() self.name = name self.nikname = nikname } }
這個在涉及到繼承的時候還有很多擴展,這里就不一一列舉了。
http://www.wenjuan.com/s/77N7Jj
總之,這些新的關鍵字和新的特性都讓這門新的語言變得靈活和安全。雖然初期會給你帶了很多困惑和不便,但是你會很快愛上這門語言的。
歡迎訪問傾劍飛血的博客:http://www.cnblogs.com/jacklandrin/p/3782831.html