• Swift基础语法: 28


    在Swift中, 我们也有相应的实例方法, Self属性, 还有类型方法, 其实这些都是和OC中的方法类似的, 只是语法上有些不同, 下面让我们一起来看看吧:


    1.实例方法

    实例方法是属于某个特定类、结构体或者枚举类型实例的方法, 是用来访问, 修改实例属性, 也提供相应的与实例相关的功能, 下面让我们一起来看看例子:

    class Counter {
        var count = 0
        func increment() {
            count++
        }
        func incrementBy(amount: Int) {
            count += amount
        }
        func reset() {
            count = 0
        }
    }
    
    let counter = Counter()
    println(counter.count)
    // 打印出来的结果: 0
    
    counter.increment()
    println(counter.count)
    // 打印出来的结果: 1
    
    counter.incrementBy(5)
    println(counter.count)
    // 打印出来的结果: 6
    
    counter.reset()
    println(counter.count)
    // 打印出来的结果: 0

    PS: 在方法中, 除了有内部参数之外, 其实还可以导入外部参数, 当然, 方法参数也是如此, 但方法和函数的局部名称和外部名称的默认行为是不一样的, 比如:

    class Counter {
        var count: Int = 0
        func incrementBy(amount: Int, numberOfTimes: Int) {
            count += amount * numberOfTimes
        }
    }
    
    let counter = Counter()
    counter.incrementBy(5, numberOfTimes: 3)
    
    println(counter.count)
    // 打印出来的结果: 15

    PS: 在这个方法中, 它会把amount这个参数当成一个内部参数, 而numberOfTimes就当成一个外部参数, 如果要去记忆它们的话, 那么就想成一个不需要写参数名, 一个需要写参数名就OK了.


    2.Self属性

    类型的每一个实例都有一个隐含属性叫做 self, self 完全等同于该实例本身, 你可以在一个实例的实例方法中使用这个隐含的 self 属性来引用当前实例, 比如:

    func increment() {
        self.count++
    }

    但在Swift中, 我们是不需要经常写Self的, 因为只要在一个方法中使用一个已知的 属性或者方法名称,如果你没有明确的写 self, 那么Swift就假定你是指当前实例的属性或者方法, 让我们来看看例子:

    struct Point {
        var x=0.0,y=0.0
        func isToTheRightOfX(x: Double) -> Bool {
            return self.x > x
        }
    }
    
    let somePoint = Point(x: 4.0, y: 5.0)
    
    if somePoint.isToTheRightOfX(1.0) {
        println("This point is to the right of the line where x == 1.0")
    }
    // 打印出来的结果: This point is to the right of the line where x == 1.0

    PS: 如果不使用 self 前缀,Swift 就认为两次使用的 x 都指的是名称为 x 的函数参数。

    在我们开发的过程中, 我们或许有特殊的需求, 需要去修改实例中的一些值类型, 但直接修改是不可能会实现的, 在Swift中需要用到一些特殊的手段, 该方法我们称为变异方法, 让我们一起来看看吧:

    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))")
    // 打印出来的结果: This point is to the right of the line where x == 1.0

    PS: 这里要注意一下, mutatinga该关键字只能用在变量里, 如果使用在常量里的话, 编译器是会报错的, 比如:

    let fixedPoint = Point(x: 3.0, y: 3.0)
    fixedPoint.moveByX(1.0, y: 2.0)
    // 报错: Immutable value of type 'Point' only has mutating members named 'moveByX'

    报错

    但是mutating该方法是可以在Self里使用的, 比如:

    struct Point {
        var x = 0.0, y = 0.0
        mutating func moveByX(deltaX: Double, y deltaY: Double) {
            self = Point(x: x + deltaX, y: y + deltaY)
        }
    }
    
    enum TriStateSwitch {
        case Off, Low, High
        mutating func next() {
        switch self {
            case Off:
                self = Low
            case Low:
                self = High
            case High:
                self = Off
            }
        }
    }
    
    var ovenLight = TriStateSwitch.Low
    println(ovenLight.hashValue)
    // 打印出来的结果: 1
    
    ovenLight.next()
    println(ovenLight.hashValue)
    // 打印出来的结果: 2
    
    ovenLight.next()
    println(ovenLight.hashValue)
    // 打印出来的结果: 0

    3.类型方法

    在Swift中也有类型方法, 但定义方式不太一样, 需要在func关键字之前加一个class, 这样子就变成了类方法了, 如果要声明结构体或者是枚举方法, 那就要在func前面加static这个关键字, 和OC不同的是, Swift可以为所有的类, 结构体, 枚举定义类方法, 让我们来看看例子吧:

    class SomeClass {
    class func someTypeMethod() {
            println("abc")
        }
    }
    SomeClass.someTypeMethod()
    // 打印出来的结果: abc

    PS: 因为SomeClass是类方法, 所以我们不需要实例某个对象才调用, 我们可以直接去使用.

    我们来看一个比较综合一点的例子:

    struct LevelTracker {
        static var highestUnlockedLevel = 1
        static func unlockLevel(level: Int) {
            if level > highestUnlockedLevel {
                highestUnlockedLevel = level
            }
        }
    
        static func levelIsUnlocked(level: Int) -> Bool {
            return level <= highestUnlockedLevel
        }
    
        var currentLevel = 1
        mutating func advanceToLevel(level: Int) -> Bool {
            if LevelTracker.levelIsUnlocked(level) {
                currentLevel = level
                return true
            } else {
                return false
            }
        }
    }

    PS: 这个例子中, 我们是在结构体中定义了静态变量, 结构体方法, 变异方法.

    然后我们需要再定义一个类, 用来监听LeveTracker该结构体:

    class Player {
        var tracker = LevelTracker()
        let playerName: String
        func completedLevel(level: Int) {
            LevelTracker.unlockLevel(level + 1)
            tracker.advanceToLevel(level + 1)
        }
        init (name: String) {
            playerName = name
        }
    }
    
    var player = Player(name: "Argyrios")
    player.completedLevel(1)
    println("highest unlocked level is now (LevelTracker.highestUnlockedLevel)")
    // 打印出来的结果: highest unlocked level is now 2
    
    player = Player(name: "Beto")
    if player.tracker.advanceToLevel(6) {
            println("player is now on level 6")
        } else {
            println("level 6 has not yet been unlocked")
    }
    // 打印出来的结果: level 6 has not yet been unlocked

    好了, 这次我们就讲到这里, 下次我们继续~~~

  • 相关阅读:
    MySQL中如何使用布尔类型【转】
    你所不知道的Android Studio调试技巧【转】
    设计模式之工厂模式(factory pattern)【转】
    layuiadmin+tp5后台内容管理系统【转】
    PHPStorm怎么修改选中的背景颜色呢?【转】
    PHP保留两位小数的几种方法【转】
    jquery的css()函数同时设置多个css属性值
    Flutter text设置行间距【转】
    Flutter入门-布局Container、Padding、Align、Center【转】
    redis下载地址
  • 原文地址:https://www.cnblogs.com/iOSCain/p/4529360.html
Copyright © 2020-2023  润新知