Рассмотрим этот @propertyWrapper:
@propertyWrapper struct Capitalized {
var wrappedValue: String {
didSet { wrappedValue = wrappedValue.capitalized }
}
init(wrappedValue: String) {
self.wrappedValue = wrappedValue.capitalized
}
}
Используя его следующим образом:
struct User {
@Capitalized var userName: String
}
Мой вопрос:
Зачем мне указывать аннотацию типа со свойством userName
. Разве компилятор не достаточно умен, чтобы сделать вывод, что, поскольку тип wrappedValue
of @Capitalized
равен String
, свойство userName
может быть только типа String
.
Если я опущу аннотацию типа, я получу ошибку компилятора:
Тип аннотации отсутствует в шаблоне
Я определенно согласен, что для ясности лучше предоставить аннотацию типа. Но на самом деле это не требуется для оберток свойств. Например, SwiftUI @Environment
обычно пишется без аннотации типа. Диагностика здесь просто сбивает с толку.
Диагностика здесь плохая и не указывает на реальную проблему. Проблема в том, что @Capitalized
без присвоения преобразуется в Capitalized()
, а такого инициализатора нет. Вы можете исправить это, предоставив инициализатор по умолчанию:
@propertyWrapper struct Capitalized {
...
init() { self.init(wrappedValue: "") }
}
При этом ваша структура в порядке:
struct User {
@Capitalized var userName
}
Без значения по умолчанию init()
также было бы хорошо, поскольку оно вызывает Capitalized(wrappedValue:)
:
struct User {
@Capitalized var userName = "bob"
}
Существует множество случаев, когда типы могут быть выведены (например, аргументы функций, возвращаемые значения, сохраненные свойства на основе того, как они инициализируются в
init
и т. д.). Полезно заставить их существовать в некоторых местах, как для удобства чтения человеком, так и для увеличения скорости компиляции. Некоторые языки, такие как Haskell, имеют «глобальный» вывод типов, но даже в Haskell для удобства чтения часто указываются необязательные аннотации типов.