如何使通用类的计算属性取决于类的约束 [英] How to make a computed property of a generic class depend on the class constraints

查看:104
本文介绍了如何使通用类的计算属性取决于类的约束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个协议和两个类,其中一个采用它

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 的含糊使用。如果我将 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 ().v()返回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 ().v 都返回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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆