如何使通用类的计算属性取决于类的约束 [英] How to make a computed property of a generic class depend on the class constraints
问题描述
我有一个协议和两个类,其中一个采用它
I have a protocol and two classes one of which adopts it
protocol A { }
class B1 { }
class B2: A { }
我想拥有一个计算属性a泛型类取决于类型是否采用 A
。我试过这个
I would like to have a computed property of a generic class which depends on whether the type adopts A
. I tried this
class C<T> {
var v: Int { get { return 0 } }
}
extension C where T: A {
var v: Int { get { return 1 } }
}
现在 C< B1>()。v
return 0,但是 C
抱怨 v
的含糊使用。如果我将 v
转换为它的工作方式
Now C<B1>().v
return 0, but C<B2>().v
complains about ambiguous use of v
. If I turn v
into a method it works
class D<T> {
func v() -> Int { return 0 }
}
extension D where T: A {
func v() -> Int { return 1 }
}
现在 C< B1> ().v()
返回0并且 C
返回1,如预期的那样。
Now C<B1>().v()
returns 0 and C<B2>().v()
returns 1, as intended.
为什么getter方法与method方法不同?我可以使计算的属性起作用吗?我试过
Why is the getter approach different from the method approach? Can I make the computed property work? I tried
class E<T> {
var v: Int { get { return get() } }
func get() -> Int { return 0 }
}
extension E where T: A {
func get() -> Int { return 1 }
}
但现在 E< B1> ;().v
和 E
都返回0,即只有得到
被使用。我可以强制编译器选择正确的实现吗?
but now E<B1>().v
and E<B2>().v
both return 0, i.e. only the unconstrained implementation of get
is used. Can I "force" the compiler to choose the correct implementaion?
有什么想法?对我来说,这听起来像是Swift的一个不足之处/缺陷,但我不能确定。我在XCode 8.2.1中使用Swift 3
Any thoughts? To me this sounds like a shortfall/bug of Swift, but I do not know enough to be certain. I am using Swift 3 in XCode 8.2.1
更新:我刚刚注意到,即使我的方法解决方案并不总是有效,编译器有时会决定使用更一般的无论如何实施。我不知道是什么决定了这一点(我的实际项目更大,提取一个简单的例子有点困难)......所以我可能会遇到一个更普遍的问题:如何可靠地创建泛型类的属性/方法为其类型参数的不同约束做不同的事情?
UPDATE: I just noticed that even my method solution does not always work and the compiler sometimes decides to go with the more general implementation no matter what. I am not sure what decides this (my actual project is bigger and it is a bit hard to extract a simple example)... So I might be having a more general problem: how to make a property/method of a generic class reliably do different things for different constraints of its type argument(s)?
推荐答案
如果您主动检查<
It could work if you actively check the type of T
in your computed property like this :
class D<T> {
var v: Int {
get {
if let _ = T.self as? A.Type {
return 1
} else {
return 0
}
}
}
}
let c = D<B2>()
print (c.v) // the output is 1
甚至更短:
Or even shorter :
var v: Int { return T.self is A.Type ? 1 : 0 }
这篇关于如何使通用类的计算属性取决于类的约束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!