在 SwiftUI 中使用泛型作为函数属性的默认值
Posted
技术标签:
【中文标题】在 SwiftUI 中使用泛型作为函数属性的默认值【英文标题】:Using Generics as Default Values for Function Properties in SwiftUI 【发布时间】:2020-06-15 05:57:17 【问题描述】:我正在尝试扩展 SwiftUI View 协议以简化我的代码。我在“视图”上创建了一个函数来设置填充、背景、覆盖和阴影,而不必在整个项目中每次都编写所有这些修饰符。
@inlinable public func backgroundWithBorder<Background: Shape, S: ShapeStyle>(
_ background: Background,
fill: S,
borderStyle: S,
borderWidth: CGFloat = 2,
shadow: Bool = false) -> some View
self
.padding()
.background(background.fill(fill))
.overlay(background.stroke(borderStyle, lineWidth: borderWidth))
.shadow(color: shadow ? Color.primary.opacity(0.2) : Color.clear, radius: 20, x: 0, y: 0)
上面的代码可以按需要工作,但是我想为“Background”和“S”泛型提供默认值,例如...
@inlinable public func backgroundWithBorder<Background: Shape, S: ShapeStyle>(
_ background: Background = Circle(),
fill: S = Color.blue,
borderStyle: S = Color.green,
borderWidth: CGFloat = 2,
shadow: Bool = false) -> some View
注意:我使用的是泛型,因为我并不总是想要相同的形状,而且我想在某些情况下使用渐变填充。
当我添加这些默认值时,我得到了错误
'Circle' 类型的默认参数值无法转换为类型 '背景' "插入'为!背景'
“颜色”类型的默认参数值无法转换为“S”类型 "插入'为!S'
当我这样做时,错误会在扩展中消失
@inlinable public func backgroundWithBorder<Background: Shape, S: ShapeStyle>(
_ background: Background = Circle() as! Background,
fill: S = Color.blue as! S,
borderStyle: S = Color.blue as! S,
borderWidth: CGFloat = 2,
shadow: Bool = false) -> some View
然而,在 ContentView 中,我得到了错误...
VStack
Text("Hello")
Text("World")
.backgroundWithBorder()
无法推断通用参数“背景”
无法推断通用参数“S”
同样,如果我提供值,而不是使用默认输入参数,它会构建并运行得非常好。
VStack
Text("Hello")
Text("World")
.backgroundWithBorder(Circle(),
fill: Color.blue,
borderStyle: Color.green,
shadow: true)
总之,是否可以为这些泛型提供默认值,这样我就不会在我的代码中一遍又一遍地编写相同的值?
任何帮助将不胜感激。
【问题讨论】:
【参考方案1】:我发现使用泛型和使用默认值之间存在明显的矛盾。相反,为什么不创建一个为原始函数提供硬编码值的包装函数
@inlinable public func backgroundWithBorder()
self.backgroundWithBorder(Circle(), fill: Color.blue, borderStyle: Color.green)
【讨论】:
以上是关于在 SwiftUI 中使用泛型作为函数属性的默认值的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin泛型 ① ( 泛型类 | 泛型参数 | 泛型函数 | 多泛型参数 | 泛型类型约束 )