• Swift中的一些关键字


    以下关键字关于引用传参、属性、修改成员变量、静态变量、索引和构造函数重载

    读过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

  • 相关阅读:
    Eclipse插件大全 (下)
    Eclipse插件大全 (上)
    Struts2学习笔记
    DisplayTag应用指南
    JFreeChart 2
    JFreeChart 1
    一对一直播app源码开发,多媒体消息发送优化方案
    仿比心视频聊天源码开发,网络节点数量和时延的关系
    一对一直播源码开发,保证实时性要从降低延迟下手
    小视频app源码凭什么成功出圈,守“江山”有多难?
  • 原文地址:https://www.cnblogs.com/jacklandrin/p/3782831.html
Copyright © 2020-2023  润新知