嵌套协议中的Swift关联类型未得到足够的自动推断 描述
我有一个协议,其中包含一个需要稍后推断的关联类型,名为嵌套协议中的Swift关联类型未得到足够的自动推断 描述,swift,xcode,closures,protocols,type-inference,Swift,Xcode,Closures,Protocols,Type Inference,我有一个协议,其中包含一个需要稍后推断的关联类型,名为UIViewRepresentable 然后,添加另一个协议: protocol UIViewRepresentableHelper: UIViewRepresentable { var configuration: (UIViewType) -> () { get set } } extension UIViewRepresentableHelper { func makeUIView(context: UIView
UIViewRepresentable
然后,添加另一个协议:
protocol UIViewRepresentableHelper: UIViewRepresentable {
var configuration: (UIViewType) -> () { get set }
}
extension UIViewRepresentableHelper {
func makeUIView(context: UIViewRepresentableContext<Self>) -> UIViewType { UIViewType() }
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<Self>) { configuration(uiView) }
}
编辑#3
使用单个泛型类:
public protocol UIViewRepresentableHelper: UIViewRepresentable {
var configuration: (UIViewType) -> () { get set }
}
public extension UIViewRepresentableHelper {
func makeUIView(context: UIViewRepresentableContext<Self>) -> UIViewType { UIViewType() }
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<Self>) { configuration(uiView) }
}
public struct ViewConfigurator<UIViewType: UIView>: UIViewRepresentableHelper {
public var configuration: (UIViewType) -> ()
public init(configuration: @escaping (UIViewType) -> ()) {
self.configuration = configuration
}
}
或者通过显式地指定泛型参数:
typealias ButtonConfigurator = ViewConfigurator<UIButton>
let buttonConfigurator = ButtonConfigurator { button in
print(button.title(for: .normal) ?? "empty")
}
var button = UIButton()
buttonConfigurator.configuration(button) // Optional("")
button.setTitle("some title", for: .normal)
buttonConfigurator.configuration(button) // Optional("some title")
编辑#2
因为我声明:
func updateUIView(_ uiView: UITextField, context: Context) {
}
但是一旦我把UIViewType
放进去,错误又回来了,我想我的第一个想法是正确的,编译器不能很好地处理相关的类型和闭包
编辑#1
所以问题实际上是UIViewType
和configuration
没有在同一协议中声明
我可以通过在UIViewRepresentableHelper
就像这样:
public struct ViewConfigurator<UIViewType: UIView>: UIViewRepresentableHelper
protocol UIViewRepresentableHelper: UIViewRepresentable {
typealias ViewType = UIViewType
var configuration: (ViewType) -> () { get set }
}
struct TextFieldView: UIViewRepresentableHelper {
var configuration: (UITextField)->()
}
用法:
let textFieldView = TextFieldView { textField in
print(textField.text)
}
var textField = UITextField()
textFieldView.configuration(textField) // Optional("")
textField.text = "some text"
textFieldView.configuration(textField) // Optional("some text")
编辑#3 使用单个泛型类:
public protocol UIViewRepresentableHelper: UIViewRepresentable {
var configuration: (UIViewType) -> () { get set }
}
public extension UIViewRepresentableHelper {
func makeUIView(context: UIViewRepresentableContext<Self>) -> UIViewType { UIViewType() }
func updateUIView(_ uiView: UIViewType, context: UIViewRepresentableContext<Self>) { configuration(uiView) }
}
public struct ViewConfigurator<UIViewType: UIView>: UIViewRepresentableHelper {
public var configuration: (UIViewType) -> ()
public init(configuration: @escaping (UIViewType) -> ()) {
self.configuration = configuration
}
}
或者通过显式地指定泛型参数:
typealias ButtonConfigurator = ViewConfigurator<UIButton>
let buttonConfigurator = ButtonConfigurator { button in
print(button.title(for: .normal) ?? "empty")
}
var button = UIButton()
buttonConfigurator.configuration(button) // Optional("")
button.setTitle("some title", for: .normal)
buttonConfigurator.configuration(button) // Optional("some title")
编辑#2
因为我声明:
func updateUIView(_ uiView: UITextField, context: Context) {
}
但是一旦我把UIViewType
放进去,错误又回来了,我想我的第一个想法是正确的,编译器不能很好地处理相关的类型和闭包
编辑#1
所以问题实际上是UIViewType
和configuration
没有在同一协议中声明
我可以通过在UIViewRepresentableHelper
就像这样:
public struct ViewConfigurator<UIViewType: UIView>: UIViewRepresentableHelper
protocol UIViewRepresentableHelper: UIViewRepresentable {
typealias ViewType = UIViewType
var configuration: (ViewType) -> () { get set }
}
struct TextFieldView: UIViewRepresentableHelper {
var configuration: (UITextField)->()
}
用法:
let textFieldView = TextFieldView { textField in
print(textField.text)
}
var textField = UITextField()
textFieldView.configuration(textField) // Optional("")
textField.text = "some text"
textFieldView.configuration(textField) // Optional("some text")
“可以做些什么来摆脱至少一个”什么是“他们”指的是什么?这两条错误消息?(删除的评论;我的复制不正确。)你很清楚;我只是错误地复制了它。@RobNapier最后,你删除的评论很有用;)是的,我想说这对推理机来说只是一座太远的桥。它需要计算出类型以确保它符合,它需要符合以获得扩展,我只是不认为它能计算出来。我没有看到明显的错误;这可能是编译器无法理解的。我用泛型而不是闭包重写了它,它也有同样的问题。我建议在bugs.swfit.org打开一个缺陷。“可以做些什么来摆脱至少一个”他们指的是什么?这两条错误消息?(删除的评论;我的复制不正确。)你很清楚;我只是错误地复制了它。@RobNapier最后,你删除的评论很有用;)是的,我想说这对推理机来说只是一座太远的桥。它需要计算出类型以确保它符合,它需要符合以获得扩展,我只是不认为它能计算出来。我没有看到明显的错误;这可能是编译器无法理解的。我用泛型而不是闭包重写了它,它也有同样的问题。我建议在bugs.swfit.org打开一个缺陷。虽然这允许我从原始位置删除类型,但它迫使我将其添加到其他位置。我正在寻找一种方法,斯威夫特可以自动推断类型为。我告诉它一次,我避免再做一次。(甚至作为一般约束等)。同样,这段代码也会出现同样的问题。我已经用真实世界的信息更新了我的问题。你必须在调用点指定类型。通用解决方案是一种“编码较少”的解决方案。我认为你想做的应该适用于闭包,但事实并非如此。不过,您可以只声明一个采用所需参数类型的方法。我会检查它是否工作时,我有时间,我已经尝试了这个编辑没有运气。不幸的是。是的,我理解为什么由于@RobNapier,我在扩展名中错误地声明了
func updateUIView(uiView:UITextField,context:context)
,虽然这允许我从原始位置删除类型,但它迫使我将其添加到其他位置。我正在寻找一种方法,斯威夫特可以自动推断类型为。我告诉它一次,我避免再做一次。(甚至作为一般约束等)。同样,这段代码也会出现同样的问题。我已经用真实世界的信息更新了我的问题。你必须在调用点指定类型。通用解决方案是一种“编码较少”的解决方案。我认为你想做的应该适用于闭包,但事实并非如此。不过,您可以只声明一个采用所需参数类型的方法。我会检查它是否工作时,我有时间,我已经尝试了这个编辑没有运气。不幸的是,是的,我理解为什么由于@RobNapier,我在扩展名中错误地声明了func updateUIView(\uiView:UITextField,context:context)