Computed read-only property vs function in Swift

后端 未结 10 891
忘了有多久
忘了有多久 2020-12-04 11:00

In the Introduction to Swift WWDC session, a read-only property description is demonstrated:

class Vehicle {
    var numberOfWheels = 0
    var          


        
相关标签:
10条回答
  • 2020-12-04 11:02

    In the read-only case, a computed property should not be considered semantically equivalent to a method, even when they behave identically, because dropping the func declaration blurs the distinction between quantities that comprise the state of an instance and quantities that are merely functions of the state. You save typing () at the call site, but risk losing clarity in your code.

    As a trivial example, consider the following vector type:

    struct Vector {
        let x, y: Double
        func length() -> Double {
            return sqrt(x*x + y*y)
        }
    }
    

    By declaring the length as a method, it’s clear that it’s a function of the state, which depends only on x and y.

    On the other hand, if you were to express length as a computed property

    struct VectorWithLengthAsProperty {
        let x, y: Double
        var length: Double {
            return sqrt(x*x + y*y)
        }
    }
    

    then when you dot-tab-complete in your IDE on an instance of VectorWithLengthAsProperty, it would look as if x, y, length were properties on an equal footing, which is conceptually incorrect.

    0 讨论(0)
  • 2020-12-04 11:03

    From the performance perspective, there seems no difference. As you can see in the benchmark result.

    gist

    main.swift code snippet:

    import Foundation
    
    class MyClass {
        var prop: Int {
            return 88
        }
    
        func foo() -> Int {
            return 88
        }
    }
    
    func test(times: u_long) {
        func testProp(times: u_long) -> TimeInterval {
            let myClass = MyClass()
            let starting = Date()
            for _ in 0...times {
                _ = myClass.prop
            }
            let ending = Date()
            return ending.timeIntervalSince(starting)
        }
    
    
        func testFunc(times: u_long) -> TimeInterval {
            let myClass = MyClass()
            let starting = Date()
            for _ in 0...times {
                _ = myClass.prop
            }
            let ending = Date()
            return ending.timeIntervalSince(starting)
        }
    
        print("prop: \(testProp(times: times))")
        print("func: \(testFunc(times: times))")
    }
    
    test(times: 100000)
    test(times: 1000000)
    test(times: 10000000)
    test(times: 100000000)
    

    Output:

    prop: 0.0380070209503174 func: 0.0350250005722046 prop: 0.371925950050354 func: 0.363085985183716 prop: 3.4023300409317 func: 3.38373708724976 prop: 33.5842199325562 func: 34.8433820009232 Program ended with exit code: 0

    In Chart:

    0 讨论(0)
  • 2020-12-04 11:08

    There is a difference: If you use a property you can then eventually override it and make it read/write in a subclass.

    0 讨论(0)
  • 2020-12-04 11:08

    Historically description is a property on NSObject and many would expect that it continues the same in Swift. Adding parens after it will only add confusion.

    EDIT: After furious downvoting I have to clarify something - if it is accessed via dot syntax, it can be considered a property. It doesn't matter what's under the hood. You can't access usual methods with dot syntax.

    Besides, calling this property did not require extra parens, like in the case of Swift, which may lead to confusion.

    0 讨论(0)
  • 2020-12-04 11:09

    Since the runtime is the same, this question applies to Objective-C as well. I'd say, with properties you get

    • a possibility of adding a setter in a subclass, making the property readwrite
    • an ability to use KVO/didSet for change notifications
    • more generally, you can pass property to methods that expect key paths, e.g. fetch request sorting

    As for something specific to Swift, the only example I have is that you can use @lazy for a property.

    0 讨论(0)
  • 2020-12-04 11:11

    While a question of computed properties vs methods in general is hard and subjective, currently there is one important argument in the Swift's case for preferring methods over properties. You can use methods in Swift as pure functions which is not true for properties (as of Swift 2.0 beta). This makes methods much more powerful and useful since they can participate in functional composition.

    func fflat<A, R>(f: (A) -> () -> (R)) -> (A) -> (R) {
        return { f($0)() }
    }
    
    func fnot<A>(f: (A) -> Bool) -> (A) -> (Bool) {
        return { !f($0) }
    }
    
    extension String {
        func isEmptyAsFunc() -> Bool {
            return isEmpty
        }
    }
    
    let strings = ["Hello", "", "world"]
    
    strings.filter(fnot(fflat(String.isEmptyAsFunc)))
    
    0 讨论(0)
提交回复
热议问题