Вызов метода Swift класса factory с ведущей точкой нотации?
В недавнем вопросе у плаката была эта интересная строка кода:
self.view.backgroundColor = .whiteColor()
Я был удивлен, увидев это. Я только когда-либо видел ведущую точечную нотацию, используемую для значений перечисления. В этом случае backgroundColor
имеет тип UIColor?
, а whiteColor
- метод класса на UIColor
, который возвращает UIColor
.
Почему это работает? Это законный способ вызова метода factory?
Ответы
Ответ 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