gpt4 book ai didi

generics - 如何接受一个不太通用但动态的类型作为子类的参数?

转载 作者:可可西里 更新时间:2023-11-01 02:27:00 25 4
gpt4 key购买 nike

鉴于this question on Code Review ,灵感来自 this answer on Stack Overflow ,我带着这个问题回到了 Stack Overflow。

假设我有一个包含许多子类的类,比如说 UIControl。我想用一个方法扩展这个类。此方法应将其相同类型的对象作为其参数之一。但是对于任何和所有这个类的子类,这个方法应该只接受它自己类型的参数。例如,UIButton 应该只接受类型为 UIButton 的参数,而 UILabel 应该只接受类型为 UILabel 的参数。

尝试了什么?

首先:

func foo<T: UIControl>(arg: T) {
// do stuff
}

就编译和运行而言,这是有效的,但它不强制执行。我可以传递任何 UIControl 子类,无论我实际调用什么类型的 foo

下一步:

func foo(arg: Self) {
// do stuff
}

还有:

func foo<T: Self>(arg: T) {
// do stuff
}

这些都不起作用,但这是一个想法。不编译,不能像这样使用 Self

还试过:

func foo(arg: self.dynamicType) {
// do stuff
}

和:

func foo(arg: typeof(self)) {
// do stuff
}

而且这些仍然没有一个有效——无法编译(这些错误很奇怪而且合理...)。

然后:我没有想法了。

现在,一般来说,我们可能会争辩说使用泛型很好,因为我们只打算用它做我们将泛型约束到的父对象能够做的事情,但是如果我们想返回这个对象怎么办其他人会知道并需要它作为比我们定义的父类型更具体的东西?

例如,如果我们正在编写一个函数来添加回调:

func doCallBack<T: UIControl>(callback: (T) -> Void)) {
callback(self)
}

在回调 block 中,用户能够使用和引用参数作为其特定类型对我们来说很重要,但对我们来说,当我们调用 doCallBack UIButtonT的类型只能是一个UIButton,但是当我们在一个上调用doCallBack UILabelT 的类型只能是一个UILabel,对于每种类型的UIControl 等等。

这完全可以实现吗?

最佳答案

But for any and all of this classes subclasses, this method should only accept an argument of its own type.

这对于继承的工作方式来说是不可能的。

考虑

class Foo : UIControl
class Bar : Foo

所以 Foo 必须有一个带有签名的方法 func foo(arg: Foo)。由于 BarFoo 的子类,它将继承一个带有签名的方法 func foo(arg: Foo) (或者用一个该签名的方法)。在任何情况下,参数类型都不能比 Foo 窄,因为这样 Bar 就不能像继承要求的那样适本地替代 Foo .因此,Barfoo 方法不能“只接受它自己类型的参数”。

关于generics - 如何接受一个不太通用但动态的类型作为子类的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27434346/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com