Calling a Swift class factory method with leading dot notation?

前端 未结 3 1656
甜味超标
甜味超标 2020-11-30 04:40

In a recent question, the poster had this interesting line of code:

self.view.backgroundColor = .whiteColor()

I was surprised to see this.

相关标签:
3条回答
  • 2020-11-30 05:14

    I could not find anything along the lines in the documentation. However, the way it works, I believe, is that Swift knows which type is being in context from self.view.backgroundColor, therefore expression starting directly with a dot should be a static on that type (either a static method or static property).

    The following works nicely:

    struct Foo {
        static func fooMethod() -> Foo {
            return Foo()
        }
    
        static var fooProperty: Foo = Foo()
    }
    
    var foo: Foo
    
    foo = .fooMethod()
    
    foo = .fooProperty
    
    0 讨论(0)
  • 2020-11-30 05:16

    Looks like the rule is: if a type has a static method that returns that type, you can skip the type’s name if the return type is already determined:

    struct S {
        static func staticmethod() -> S {
            return S()
        }
        static var staticproperty: S {
            return S()
        }
    }
    
    let s1: S = .staticmethod()
    let s2: S = .staticproperty
    

    I wonder if this is intentional, or a side-effect of the implementation of Enums which, given this feature, could maybe be thought of as syntactic sugar for something like this:

    struct FakeEnum {
        let raw: Int
        static var FirstCase:  FakeEnum  { return FakeEnum(raw: 0) }
        static var SecondCase: FakeEnum  { return FakeEnum(raw: 1) }
    }
    
    let e: FakeEnum = .FirstCase
    
    0 讨论(0)
  • 2020-11-30 05:24

    This feature is called "Implicit Member Expression"

    An implicit member expression is an abbreviated way to access a member of a type, such as an enumeration case or a class method, in a context where type inference can determine the implied type. It has the following form:

    .member name


    But, as of right now, I advise you should not use this feature in Optional or ImplicitlyUnwrappedOptional context.

    Although this works:

    // store in Optional variable
    let col: UIColor?
    col = .redColor()
    
    // pass to function
    func f(arg:UIColor?) { println(arg) }
    f(.redColor())
    

    This crashes the compiler :(

    func f(arg:UIColor?, arg2:Int) { println(arg) }
    //                 ^^^^^^^^^^ just added this.
    f(.redColor(), 1)
    

    The compiler has some bugs. see: does swift not allow initialization in function parameters?

    0 讨论(0)
提交回复
热议问题