繁体   English   中英

如何在Swift中将通用类型限制为另一个通用类型?

[英]How to constraint generic type to another generic type in Swift?

我想做这样的事情:

class Config<T> {
  func configure(x:T)
  // constraint B to be subclass of A
  class func apply<A,B:A>(c:Config<A>, to:B) {
    c.configure(to)
  } 
}

因此,例如,稍后,我可以将Config应用于UILabel:

class RedViewConfig<T:UIView> : Config<T> {
  func configure(x:T) {
    x.backgroundColor = .redColor();
  } 
}

let label = UILabel() 
Config.apply(RedViewConfig(), to:label)

或扩展Config类:

class RedLabelConfig<T:UILabel> : RedViewConfig<T> {
  func configure(x:T) {
    super.configure(x)
    x.textColor = .redColor();
  } 
}

Config.apply(RedLabelConfig(), to:label)

我尝试这样做,但是我不能约束类。 因此,我尝试使用协议和关联类型,但是在子类化时,在重写关联类型时发现了问题( 例如 )。

您实际上是否需要通用参数B 如果您的参数to:也输入为A ,则它可以是A任何子类型。 像这样:

class View {}
class LabelView : View {}

class Config<T> {
  func configure(x:T) { print ("Configured: \(x)") }  
}

func applyConfig<A> (c:Config<A>, to:A) {
  c.configure(to)
}

applyConfig(Config<View>(), to: LabelView())

类使这种方式过于复杂。 如果可以避免的话,在Swift中继承几乎总是一个坏主意。

结构虽然更接近,但仍然使它过于复杂和受限。

实际上,这些配置器只是功能。 他们拿东西,然后对它做点什么,什么也没返回。 它们只是T -> Void 让我们构建其中一些。

func RedViewConfig(view: UIView) { view.backgroundColor = .redColor() }
func VisibleConfig(view: UIView) { view.hidden = false }

我们可以很容易地使用它们:

let label = UILabel()
VisibleConfig(label)

如果它们的类型兼容,我们可以组成它们(像super ,但没有行李):

func RedLabelConfig(label: UILabel) {
    RedViewConfig(label)
    label.textColor = .redColor()
}

我们可以在数据结构中传递它们,编译器将为我们应用正确的协方差:

let configs = [RedLabelConfig, VisibleConfig]
// [UILabel -> ()]
// This has correctly typed visibleConfig as taking `UILabel`,
// even though visibleConfig takes `UIView`

// And we can apply them
for config in configs { config(label) }

现在,如果我们需要其他语法,我们也可以轻松构建它们。 更像您的原始作品:

func applyConfig<T>(f: T -> Void, to: T) {
    f(to)
}
applyConfig(VisibleConfig, to: label)

甚至更接近您的原始照片:

struct Config {
    static func apply<T>(config: T -> Void, to: T) { config(to) }
}

Config.apply(VisibleConfig, to: label)

关键是,仅在此处使用函数就可以使一切变得非常灵活,而无需增加类继承甚至结构的复杂性。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM