Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a Swift class factory method with leading dot notation?

Tags:

swift

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

self.view.backgroundColor = .whiteColor() 

I was surprised to see this. I've only ever seen the leading dot notation used for enum values. In this case, backgroundColor is of type UIColor? and whiteColor is a class method on UIColor that returns a UIColor.

Why does this work? It this a legitimate way to call a factory method?

like image 874
vacawama Avatar asked Mar 01 '15 13:03

vacawama


2 Answers

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?

like image 83
rintaro Avatar answered Sep 21 '22 00:09

rintaro


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 
like image 21
Airspeed Velocity Avatar answered Sep 24 '22 00:09

Airspeed Velocity