Swift 无法转换类型为';通用<;字符串>';到预期的参数类型';通用<;任何>';

Swift 无法转换类型为';通用<;字符串>';到预期的参数类型';通用<;任何>';,swift,generics,compiler-errors,swift3,Swift,Generics,Compiler Errors,Swift3,我很困惑。。。我甚至不知道编译器认为可能发生了什么,但我90%确信这应该是可能的: 类泛型{ } 协议Foo{ 功能条(baz:通用) } 类SomeFoo:Foo{ 功能条(baz:通用){ 打印(“得到”,baz) } } 让someFoo=someFoo() 让generic=generic() someFoo.bar(generic)//编译错误:无法将类型为“generic”的值转换为预期的参数类型“generic” 这里发生了什么,解决办法是什么?当然,一定有一些解决办法…这叫做协

我很困惑。。。我甚至不知道编译器认为可能发生了什么,但我90%确信这应该是可能的:

类泛型{
}
协议Foo{
功能条(baz:通用)
}
类SomeFoo:Foo{
功能条(baz:通用){
打印(“得到”,baz)
}
}
让someFoo=someFoo()
让generic=generic()
someFoo.bar(generic)//编译错误:无法将类型为“generic”的值转换为预期的参数类型“generic”

这里发生了什么,解决办法是什么?当然,一定有一些解决办法…

这叫做协方差,Swift中的用户类型不支持协方差(我知道的数组除外)。顺便说一句,Objective-C泛型在某种程度上支持协方差。
在您的情况下,我可以从两个选项中选择:

  • 使条形函数通用
  • 创建foo函数将接受的非通用协议,并在
    generic
    类中实现该协议

  • 为什么
    Generic
    应该转换为
    Generic,但是
    字符串是任意的
    。。。如果函数接受了
    Any
    ,我给了它一个
    String
    ,它不会抱怨
    String
    Any
    ,但是
    (String)->Void
    不是
    (Any)->Void
    。我的观点是,不能假设这总是有效的。某些语言允许您指定它应该工作;Swift的当前版本不是其中之一。要清楚,假设您有一个函数
    f(u2;:String)->Void
    。然后假设您有
    func callFunc(x:(Any)->Void)){x(42)}
    ,这是完全有效的代码。如果
    (String)->Void
    可转换为
    (Any)->Void
    ,则可以调用
    callFunc(f)
    ,这显然是无效的,因为
    42
    不是字符串。@jtbandes这是一个很好的答案:d