gpt4 book ai didi

ios - Swift通用闭包和

转载 作者:行者123 更新时间:2023-12-01 18:34:30 24 4
gpt4 key购买 nike

您能告诉我,为什么一个代码可以正常工作,而另一个代码却不能正常工作吗?

该代码可以正常工作:

typealias StyleClosure<T: UIView> = (T) -> ()

func +<T>(lhs: @escaping StyleClosure<T>,
rhs: @escaping StyleClosure<T>) -> StyleClosure<T> {
return { (value: T) -> Void in
lhs(value)
rhs(value)
}
}

let s1: StyleClosure<UIView> = { (view: UIView) in
view.layer.cornerRadius = 1
}

let s2: StyleClosure<UILabel> = { (view: UILabel) in
view.font = UIFont.systemFont(ofSize: 14)
}

let s3 = s1 + s2

s3是闭包,我可以将UILabel传递给它。 func +可以接受两个包含不同类型的闭包-UIView和UILabel。

但是以下代码给出了一个错误:
class Styler<T: UIView> {
private let closure: (T) -> ()
init(_ closure: @escaping (T) -> ()) {
self.closure = closure
}
func apply(_ view: T) {
self.closure(view)
}
}
func +<T>(lhs: Styler<T>, rhs: Styler<T>) -> Styler<T> {
return Styler { (value: T) in
lhs.apply(value)
rhs.apply(value)
}
}

let styler1: Styler<UILabel> = Styler { (label: UILabel) -> Void in
label.backgroundColor = UIColor.red
}

let styler2: Styler<UIView> = Styler { (view: UIView) -> Void in
view.backgroundColor = UIColor.green
}

let styler3 = styler1 + styler2

此代码给出以下编译错误:
Cannot convert value of type 'Styler<UIView>' to expected argument type 'Styler<UILabel>'

我有点理解,为什么第二个代码给出错误。您有什么主意,为什么第一个代码没有错误?

最佳答案

您正在遇到Swift generic coercion misunderstanding的问题。 Swift中的泛型类型是不变的,这意味着Styler<A>Styler<B>是完全不相关的类型,即使AB是相关的(例如子类)。

这就是Style<UILabel>Styler<UIView>不相关的原因。但是,闭包(以及函数)是变量(如here所述)-返回类型是协变的,而参数类型是协变的,这就是第一个示例起作用的原因。

因此,您可以将UILabel传递给Styler<UIView>.apply,因为这是一个简单的函数调用,它接受声明的输入参数类型的子类。

let styler1: Styler<UIView> = Styler { (label: UIView) -> Void in
label.backgroundColor = UIColor.red
}

let styler2: Styler<UIView> = Styler { (view: UIView) -> Void in
view.backgroundColor = UIColor.green
}

let styler3 = styler1 + styler2

styler1.apply(UILabel())

关于ios - Swift通用闭包和,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62341988/

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