Подтвердить что ты не робот

Вызов метода Swift класса factory с ведущей точкой нотации?

В недавнем вопросе у плаката была эта интересная строка кода:

self.view.backgroundColor = .whiteColor()

Я был удивлен, увидев это. Я только когда-либо видел ведущую точечную нотацию, используемую для значений перечисления. В этом случае backgroundColor имеет тип UIColor?, а whiteColor - метод класса на UIColor, который возвращает UIColor.

Почему это работает? Это законный способ вызова метода factory?

4b9b3361

Ответ 1

Эта функция называется Неявное выражение участника"

Неявное выражение члена является сокращенным способом доступа к члену типа, например, к перечислению или методу класса, в контексте, где вывод типа может определять подразумеваемый тип. Он имеет следующий вид:

. member name


Но на данный момент я советую вам не использовать эту функцию в контексте Optional или ImplicitlyUnwrappedOptional.

Хотя это работает:

// store in Optional variable
let col: UIColor?
col = .redColor()

// pass to function
func f(arg:UIColor?) { println(arg) }
f(.redColor())

Сбой компилятора: (

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

У компилятора есть некоторые ошибки. см. не позволяет ли инициализировать параметры функции?

Ответ 2

Похоже, что правило: если тип имеет статический метод, который возвращает этот тип, вы можете пропустить имя типа, если тип возврата уже определен:

struct S {
    static func staticmethod() -> S {
        return S()
    }
    static var staticproperty: S {
        return S()
    }
}

let s1: S = .staticmethod()
let s2: S = .staticproperty

Интересно, является ли это преднамеренным или побочным эффектом реализации Enums, который, учитывая эту функцию, можно было бы рассматривать как синтаксический сахар для чего-то вроде этого:

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

Ответ 3

Я не мог найти ничего по строкам в документации. Однако, как мне кажется, способ, которым он работает, заключается в том, что Swift знает, какой тип находится в контексте от self.view.backgroundColor, поэтому выражение, начинающееся непосредственно с точки, должно быть статичным в этом типе (либо статическим методом, либо статическим свойством).

Следующее работает красиво:

struct Foo {
    static func fooMethod() -> Foo {
        return Foo()
    }

    static var fooProperty: Foo = Foo()
}

var foo: Foo

foo = .fooMethod()

foo = .fooProperty