首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI视图中较短的泛型语法

SwiftUI视图中较短的泛型语法
EN

Stack Overflow用户
提问于 2021-10-02 14:47:15
回答 1查看 63关注 0票数 0

是否有更好的泛型语法?贝莱德的代码在一开始就给了我巨大的丑陋的泛型定义。

代码语言:javascript
复制
struct ViewUserSettings<TypeGif: ModelGifProtocol, TypeFont: ModelFontProtocol, TypeMagicText: ModelMagicTextProtocol, TypePreSetAnswer: ModelPreSetAnswerProtocol>: View where TypeGif: Hashable, TypeFont: Hashable, TypeMagicText: Hashable, TypePreSetAnswer: Hashable

我必须在泛型中定义Hashable,否则编译器在SwiftUI ForEach中使用此协议时会出错。

ModelGif.swift

代码语言:javascript
复制
// MARK: - Protocol
enum GifType: String, Codable {
    
    case fooA = "fooA more"
    case fooB = "fooB more"
    case fooC = "fooC more"
    
    // MARK: Properties
    var fileName600px: String {
        switch self {
        case .fooA: return "fooAHQ"
        case .fooB: return "fooBHQ"
        case .fooC: return "fooCHQ"
        }
    }
    
    var fileName80px: String {
        switch self {
        case .fooA: return "fooALQ"
        case .fooB: return "fooBLQ"
        case .fooC: return "fooCLQ"
        }
    }
    
}

protocol ModelGifProtocol: Codable {
    var gif: GifType { get }
}

// MARK: - Module
struct ModelGif: ModelGifProtocol, Hashable {
    
    // MARK: Properties
    let gif: GifType
    
    // MARK: Initialization
    init(_ gif: GifType) {
        self.gif = gif
    }
    
    // MARK: Static Properties
    static var fooA = Self(.fooA)
    static var fooB = Self(.fooB)
    static var fooC = Self(.fooC)
    
}

ModelMagicText.swift

代码语言:javascript
复制
// MARK: - Protocol
protocol ModelMagicTextProtocol: Codable {
    var id: UUID { get }
    var context: String { get }
    init(_ context: String, id: UUID) throws
    init(_ context: String) throws
}

// MARK: - Module
struct ModelMagicText: ModelMagicTextProtocol, Hashable {
    
    // MARK: Properties
    let id: UUID
    let context: String
    
    // MARK: Initialization
    init(_ context: String, id: UUID) throws {
        guard context.count <= 30 else { throw ContextError.tooLong } // restricted at ViewAnimatingCircleText.modifyDynamicText()
        self.context = context.uppercased()
        self.id = id
    }
    
    init(_ context: String) throws {
       try self.init(context, id: UUID())
    }
    
    init(_ model: ModelMagicTextProtocol) throws {
        try self.init(model.context, id: model.id)
    }
    
    // MARK: Static Properties
    static let defaultText = try! ModelMagicText("foooooooooooo")
    
}

// MARK: - Extension: ContextError
extension ModelMagicText {
    
    enum ContextError: Error {
        case tooLong
    }
    
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-02 17:55:09

我们可以更好地使用多行设置格式。我们还可以将Hashable约束移到泛型参数列表中:

代码语言:javascript
复制
struct ViewUserSettings<
    TypeGif: ModelGifProtocol & Hashable,
    TypeFont: ModelFontProtocol & Hashable,
    TypeMagicText: ModelMagicTextProtocol & Hashable,
    TypePreSetAnswer: ModelPreSetAnswerProtocol & Hashable
>: View {
    var gif: TypeGif
    var font: TypeFont
    var magicText: TypeMagicText
    var preSetAnswer: TypePreSetAnswer

    var body: some View { EmptyView() }
}

只有在具有相等约束时才需要where子句,但是示例代码没有任何等式约束。

如果将每个模型协议更改为从Hashable继承,则可以完全消除Hashable约束:

代码语言:javascript
复制
protocol ModelGifProtocol: Hashable { }
protocol ModelFontProtocol: Hashable { }
protocol ModelMagicTextProtocol: Hashable { }
protocol ModelPreSetAnswerProtocol: Hashable { }

struct ViewUserSettings<
    TypeGif: ModelGifProtocol,
    TypeFont: ModelFontProtocol,
    TypeMagicText: ModelMagicTextProtocol,
    TypePreSetAnswer: ModelPreSetAnswerProtocol
>: View {
    ...

还有一个问题,你是否需要这样冗长的名字。你真的需要TypeModel前缀吗?

代码语言:javascript
复制
protocol GifProtocol: Hashable { }
protocol FontProtocol: Hashable { }
protocol MagicTextProtocol: Hashable { }
protocol PreSetAnswerProtocol: Hashable { }

struct ViewUserSettings<
    Gif: GifProtocol,
    Font: FontProtocol,
    MagicText: MagicTextProtocol,
    PreSetAnswer: PreSetAnswerProtocol
>: View {
    var gif: Gif
    var font: Font
    var magicText: MagicText
    var preSetAnswer: PreSetAnswer
    
    var body: some View { EmptyView() }
}

请记住,您仍然可以将SwiftUI的Font类型称为SwiftUI.Font in ViewUserSettings

您没有给出如何定义您的协议的任何细节。你真的需要你自己的ModelFontProtocol吗?SwiftUI的Font已经是Hashable,所以如果您只需要使用具体的Font类型,代码就会更简单。也许您也可以使用具体的类型来代替您的其他协议,但是我们不能不了解它们是如何定义的。

如果您对多个视图使用相同的类型参数和约束集,则有一些方法可以将常见的内容分解出来。如果是这样的话,你应该编辑你的问题,以包括更多的示例代码。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69417961

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档