【发布时间】:2020-09-06 12:51:39
【问题描述】:
这个问题最好用一些代码来解释。
步骤 1
public struct Example<Content: View> {
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func contentView() -> Content {
self.content()
}
}
第二步
现在当我添加一个内部结构时,编译器会抱怨不支持静态存储属性。
public struct Example<Content: View> {
let content: () -> Content
init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
func contentView() -> Content {
self.content()
}
public struct ActionKey: Hashable, Equatable, RawRepresentable {
public static let cancelButtonClicked = ActionKey("cancelButtonClicked") // Static stored properties not supported in generic types
public static func == (lhs: ActionKey, rhs: ActionKey) -> Bool {
return lhs.rawValue == rhs.rawValue
}
public let rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
public init(_ rawValue: String) {
self.init(rawValue: rawValue)
}
}
}
第三步
为了消除错误,我们需要将其转换为计算变量。
public static var cancelButtonClicked: ActionKey { get { ActionKey("cancelButtonClicked") } }
问题
除了这已经很烦人之外,它变得更糟。我们还需要为一个完全不依赖它的结构提供一个通用参数。
_ = Example.ActionKey(rawValue: "cancelButtonClicked") // Generic parameter 'Content' could not be inferred
// Fix
_ = Example<AnyView>.ActionKey(rawValue: "cancelButtonClicked")
如果我们能以某种方式避免将泛型类型放在外部作用域中,我们就可以避免它。但是,将类型存储在变量中不会让我使用它。所以我被困住了。有人回答吗?
public struct Example<Content: View> {
let content: Any
let contentType: Any.Type
init<Content>(@ViewBuilder content: @escaping () -> Content) {
self.content = content
self.contentType = Content.self
}
func contentView() -> ?? {
self.content() // ??
}
public struct ActionKey: Hashable, Equatable, RawRepresentable {
public static var cancelButtonClicked: ActionKey { get { ActionKey("cancelButtonClicked") } }
public static func == (lhs: ActionKey, rhs: ActionKey) -> Bool {
return lhs.rawValue == rhs.rawValue
}
public let rawValue: String
public init(rawValue: String) {
self.rawValue = rawValue
}
public init(_ rawValue: String) {
self.init(rawValue: rawValue)
}
}
}
将内部结构放在外面是唯一的解决方案吗?
【问题讨论】:
-
获取非泛型ActionKey,实际上是独立的,类型出泛型Example类型。
-
当然可以把它放在外面。但是内部结构会更有意义,因为 ActionKey 仅属于 Example。因此,Example.ActionKey 和单独在结构中使用 ActionKey 比将结构放在外面并调用它 ExampleActionKey 更好。
-
但这是您未能掌握的部分。你永远不能说 Example.ActionKey 因为没有这样的类型。示例不是单一类型。它是通用的!这意味着
Example<String>是一个类型,Example<Int>是一个独立且不相关的类型。您正在尝试为其中的每一个定义一个内部类型。