Значительным ограничением является T: ExpressibleByStringLiteral
.Это то, что позволяет что-то инициализировать из строкового литерала.
func doSomething<T: Collection>(value: T = "abc")
where T.Element == Character, T: ExpressibleByStringLiteral {
// ...
}
Как отмечает Лео Дабус, T.Element == Character
технически не требуется, но удаление его меняет смысл.То, что что-то является коллекцией и может быть инициализировано строковым литералом, не означает, что его элементы являются символами.
Стоит также отметить, что, хотя все это возможно, это, как правило, плохое Свифт ИМО.Swift не имеет никакого способа выразить, что является типом по умолчанию , поэтому doSomething()
во всех этих случаях приводит к тому, что «общий параметр« T »не может быть выведен».
ПравильныйРешение IMO - это перегрузка, которая позволяет избежать всех этих проблем:
func doSomething<T: StringProtocol>(value: T) {
}
func doSomething() {
doSomething(value: "abc")
}
Это позволяет вам сделать параметр по умолчанию не просто «чем-то, что может быть инициализировано литералом "abc"
», а тем, что вы на самом делеозначают: значением по умолчанию является String "abc".
Как правило, параметры по умолчанию являются просто удобством для перегрузок, поэтому вы можете вообще заменить любой параметр по умолчанию явной перегрузкой, в которой отсутствует этот параметр.