fbe*_*rdo 5 generics ios swift
我试图在协议中声明一个函数,该函数强制符合它的类型返回相同协议的值,但具有特定的关联类型:
protocol Protocol {
typealias ValueType
var value : ValueType? {get}
func getProtocolString<A where A : Protocol, A.ValueType == String>() -> A
}
Run Code Online (Sandbox Code Playgroud)
这编译.当我尝试创建一个符合它的类时,我得到了错误:
class AClass<T> : Protocol {
var value : T?
func getProtocolString<A where A : Protocol, A.ValueType == String>() -> A {
return AClass<String>()
}
}
Run Code Online (Sandbox Code Playgroud)
错误是'AClass'不能转换为'A'.
我错过了什么吗?这甚至可能吗?
谢谢
问题在于将受协议约束的通用占位符与协议本身混淆了。Here\xe2\x80\x99s 是一个更简单的示例,类似于您的代码,尝试使其清晰:
\n\n// first, define a protocol and two structs that conform to it\nprotocol P { }\nstruct S1: P { }\nstruct S2: P { }\n\n// now, a function that returns an object in the form\n// of a reference to protocol P\nfunc f() -> P {\n // S1 conforms to P so that\xe2\x80\x99s fine \n return S1()\n}\n// ok all well and good, this works fine:\nlet obj = f()\n\n// now, to do something similar to your example code,\n// declare a generic function that returns a generic\n// placeholder that is _constrained_ by P\n// This will NOT compile:\nfunc g<T: P>() -> T { return S1() }\nRun Code Online (Sandbox Code Playgroud)\n\n为什么这不能编译?
\n\n泛型函数的工作方式是,在编译时,当您调用该函数时,编译器会决定占位符T需要是什么类型,然后为您编写一个函数,其中所有出现的 都T替换为该类型。
因此,在下面的示例中,T应替换为S1:
let obj1: S1 = g()\n// because T needs to be S1, the generic function g above is \n// rewritten by the compiler like this:\nfunc g() -> S1 { return S1() }\nRun Code Online (Sandbox Code Playgroud)\n\n这看起来不错。除了,如果我们想T成为这样怎么办S2? S2符合Pso 是 的一个完全合法的值T。但这怎么行得通:
// require our result to be of type S2\nlet obj2: S2 = g()\n// so T gets replaced with S2\xe2\x80\xa6 but now we see the problem.\n// you can\xe2\x80\x99t return S1 from a function that has a return type of S2.\n// this would result in a compilation error that S2 is not\n// convertible to S1\nfunc g() -> S2 { return S1() }\nRun Code Online (Sandbox Code Playgroud)\n\n这是您收到的错误消息的来源。您的占位符A可以代表任何符合 的类型Protocol,但您试图返回符合该协议的特定类型 ( )。AClass所以它不会\xe2\x80\x99让你这么做。
| 归档时间: |
|
| 查看次数: |
285 次 |
| 最近记录: |