微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何存储通用类型以避免内部结构在Swift中要求它? 步骤1 步骤2 步骤3 问题

如何解决如何存储通用类型以避免内部结构在Swift中要求它? 步骤1 步骤2 步骤3 问题

最好用一些代码解释该问题。

步骤1

public struct Example<Content: View> {
    let content: () -> Content
    
    init(@viewbuilder content: @escaping () -> Content) {
        self.content = content
    }
    
    func contentView() -> Content {
        self.content()
    }
}

步骤2

现在,当我添加一个内部结构时,编译器会抱怨不支持静态存储的属性

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)
        }
    }
}

步骤3

要消除错误,我们需要将其转换为计算变量。

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,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)
        }
    }
}

是将内部结构置于所有外部的唯一解决方案吗?

解决方法

这是可行的方法(但是我会把它放在外面,就像ButtonStyleButton之外)……无论如何,这里是:

public struct Example {
    private let content: AnyView

    init<Content: View>(@ViewBuilder content: @escaping () -> Content) {
        self.content = AnyView(content())
    }

    func contentView() -> some View {
        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)
        }
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。