Swift 如何为具有类型约束的泛型函数提供默认参数?

Swift 如何为具有类型约束的泛型函数提供默认参数?,swift,string,compiler-errors,Swift,String,Compiler Errors,以下函数定义是合法的: func doSomething<T: StringProtocol>(value: T = "abc") { // ... } func doSomething<T: Collection>(value: T = "abc") where T.Element == Character { // ... } 编译器错误: func doSomething<T: StringProtocol>(value: T = "

以下函数定义是合法的:

func doSomething<T: StringProtocol>(value: T = "abc") {
    // ...
}
func doSomething<T: Collection>(value: T = "abc") where T.Element == Character {
    // ...
}
编译器错误:

func doSomething<T: StringProtocol>(value: T = "abc") {
    // ...
}
func doSomething<T: Collection>(value: T = "abc") where T.Element == Character {
    // ...
}
“字符串”类型的默认参数值无法转换为“T”类型

编译器似乎拥有与第一种情况相同的信息来确定
String
确实可以转换为
T
。此外,如果我删除默认参数并使用相同的值调用该函数,它将起作用:

doSomething(value: "abc")

这个函数是否可以以不同的方式编写,以便提供默认的
String
参数?这是对Swift的限制,还是仅仅是对我的思维模式的限制?

重要的限制是
T:ExpressibleByStringLiteral
。这就是允许从字符串文本初始化某些内容的原因

func doSomething<T: Collection>(value: T = "abc")
    where T.Element == Character, T: ExpressibleByStringLiteral {
    // ...
}
这使您可以设置默认参数,而不仅仅是“可以使用文本
“abc”
”初始化的内容,而是您真正的意思:默认值是字符串“abc”


通常,默认参数只是重载的便利条件,因此您通常可以用缺少该参数的显式重载替换任何默认参数。

我不知道您可以这样做;谢谢你的邀请@LeoDabus我不明白这将如何解决默认参数的情况。如何将语法
doSomething()
实现为RangeReplacableCollection的扩展?我想重载方法就是我要寻找的。可能值得一提的是,我的实际用例有点复杂,实际上并不涉及字符串,但这里的讨论非常有见地!