英文:
How to avoid spelling a complex type in Swift?
问题
这是使用SwiftUI时出现的问题,但实际上是有关Swift类型的基本问题。尝试创建如下的视图:
struct BorderedRectangle1: View {
let gesture: Gesture
init(color: Color, border: Bool) {
self.gesture = TapGesture().modifiers(.option).onEnded {
// do something
}.simultaneously(with: TapGesture().modifiers(.command).onEnded {
// do something else
})
}
var body: some View {
Rectangle()
.gesture(gesture)
}
}
但这在let gesture: Gesture
上不能编译,出现错误 Use of protocol 'Gesture' as a type must be written 'any Gesture'. Replace 'Gesture' with 'any Gesture'
通过将 let gesture: Gesture
替换为 let gesture: any Gesture
,可以消除上述错误,但在body中的 Rectangle()
上会出现另一个错误:Type 'any Gesture' cannot conform to 'Gesture'.
我可以通过将gesture属性更改为计算属性来“修复”它:
var gesture: some Gesture {
TapGesture().modifiers(.option).onEnded {
// do something
}.simultaneously(with: TapGesture().modifiers(.command).onEnded {
// do something else
})
}
我明白编译器必须能够在声明和使用位置都能够推断出类型。那么如何在保持gesture的声明为存储属性且不拼写显式类型的情况下使其工作呢?
let gesture: ?? // <= 在这里填入什么?
英文:
This is coming up while using SwiftUI bit it really is a fundamental Swift question about types. Trying to have a view like so:
struct BorderedRectangle1: View {
let gesture: Gesture
init(color: Color, border: Bool) {
self.gesture = TapGesture().modifiers(.option).onEnded {
// do something
}.simultaneously(with: TapGesture().modifiers(.command).onEnded {
// do something else
})
}
var body: some View {
Rectangle()
.gesture(gesture)
}
}
but this doesn't compile with Use of protocol 'Gesture' as a type must be written 'any Gesture'. Replace 'Gesture' with 'any Gesture'
Replacing let gesture: Gesture
=> let gesture: any Gesture
eliminates the above error but another error appears on Rectangle()
in the body: Type 'any Gesture' cannot conform to 'Gesture'.
I was able to "fix" it by making the gesture property computed:
var gesture: some Gesture {
TapGesture().modifiers(.option).onEnded {
// do something
}.simultaneously(with: TapGesture().modifiers(.command).onEnded {
// do something else
}) }
I get it that the compiler must be able to infer a type in both the declaration and use sites. So how to make it work while keeping the declaration of gesture as a stored property and without spelling the explicit type which is SimultaneousGesture<_EndedGesture<_ModifiersGesture<TapGesture>>, _EndedGesture<_ModifiersGesture<TapGesture>>>
let gesture: ?? // <= what goes in here?
答案1
得分: 0
你需要声明一个泛型类型,该类型将是存储属性的类型。该泛型类型必须符合 Gesture
。
这里是一个编译通过的代码示例:
// 创建一个符合 Gesture 的泛型类型
struct BorderedRectangle1<G: Gesture>: View {
// 属性的类型是 G
let gesture: G
init(color: Color, border: Bool) {
self.gesture = TapGesture().modifiers(.option).onEnded {
// 做一些事情
}.simultaneously(with: TapGesture().modifiers(.command).onEnded {
// 做另一些事情
}) as! G // 确保 gesture 的类型是 G
}
var body: some View {
Rectangle()
.gesture(gesture)
}
}
如果你需要将手势传递给 View
,以下是如何实现的示例:
// 创建一个符合 Gesture 的泛型类型
struct BorderedRectangle1<G: Gesture>: View {
// 属性的类型是 G
let gesture: G
// 参数的类型是 G
init(gesture: G) {
self.gesture = gesture
}
var body: some View {
Rectangle()
.gesture(gesture)
}
}
英文:
You need to declare a generic type, which will be the type of the stored property. That generic type must conform to Gesture
.
Here's a code that compiles:
// Create a generic type that conforms to Gesture
struct BorderedRectangle1<G: Gesture>: View {
// The property is of type G
let gesture: G
init(color: Color, border: Bool) {
self.gesture = TapGesture().modifiers(.option).onEnded {
// do something
}.simultaneously(with: TapGesture().modifiers(.command).onEnded {
// do something else
}) as! G // Ensure the gesture is of type G
}
var body: some View {
Rectangle()
.gesture(gesture)
}
}
If you need to pass a gesture to the View
, here's how it works:
// Create a generic type that conforms to Gesture
struct BorderedRectangle1<G: Gesture>: View {
// The property is of type G
let gesture: G
// The parameter is of type G
init(gesture: G) {
self.gesture = gesture
}
var body: some View {
Rectangle()
.gesture(gesture)
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论