如何在 Swift 中确认对 Identifiable 协议的枚举? [英] How to confirm an enumeration to Identifiable protocol in Swift?

查看:65
本文介绍了如何在 Swift 中确认对 Identifiable 协议的枚举?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用新的 SwiftUI 框架从枚举中列出案例的原始值.但是,我在使数据"符合可识别协议时遇到了麻烦,我真的找不到如何执行此操作的信息.它告诉我Initializer 'init(_:rowContent:)'要求'Data'符合'Identifiable'"存根在最后一个扩展中为我提供了一个ObjectIdentifier变量,但不知道我应该返回什么.你能告诉我怎么做吗?我如何使数据符合可识别性,以便我可以制作包含原始值的列表?

I'm trying to make a list with the raw values of the cases from an enumeration with the new SwiftUI framework. However, I'm having a trouble with conforming the 'Data' to Identifiable protocol and I really cannot find information how to do it. It tells me "Initializer 'init(_:rowContent:)' requires that 'Data' conform to 'Identifiable'" The stub provides me with an ObjectIdentifier variable in the last extension, but don't know what should I return. Could you tell me how do it? How do I conform Data to Identifiable, so I can make a list with the raw values?

enum Data: String {
    case firstCase = "First string"
    case secondCase = "Second string"
    case thirdCase = "Third string"
}

extension Data: CaseIterable {
    static let randomSet = [Data.firstCase, Data.secondCase]
}

extension Data: Identifiable {
    var id: ObjectIdentifier {
        return //what?
    }

}

//-------------------------ContentView------------------------
import SwiftUI

struct Lala: View {
    var name: String

    var body: some View {
        Text(name)
    }
}

struct ContentView: View {
    var body: some View {
        return List(Data.allCases) { i in
            Lala(name: i.rawValue)
        }
    }
}

推荐答案

⚠️ 尽量不要在内部模块中使用已经使用过的名称,例如 Data.我将在这个答案中使用 MyEnum 代替

⚠️ Try not to use already used names like Data for your internal module. I will use MyEnum instead in this answer

当某些东西符合 Identifiable 时,它必须返回一些可以通过它识别的东西.所以你应该返回一些独特的东西.对于 StringenumrawValue 是您拥有的最佳选择:

When something conforms to Identifiable, it must return something that can be identified by that. So you should return something unique to that case. For String base enum, rawValue is the best option you have:

extension MyEnum: Identifiable {
    var id: RawValue { rawValue }
}

另外,enum通常可以通过它们自己来识别:

Also, enums can usually be identified by their selves:

extension MyEnum: Identifiable {
    var id: Self { self }
}

⚠️ 注意 1:如果您返回不稳定的东西,例如 UUID()索引,这意味着您得到一个新的每次获取对象时都会出现对象,这将扼杀可重用性,并且除了视图管理问题(如转换管理等)之外,还会导致史诗般的内存和布局过程使用.

⚠️ Note 1: If you return something that is unstable, like UUID() or an index, this means you get a new object each time you get the object and this will kill reusability and can cause epic memory and layout process usage beside view management issues like transition management and etc.

看看这个添加新宠物的奇怪动画:

Take a look at this weird animation for adding a new pet:

注意 2:从 Swift 5.1 开始,单行闭包不需要 return 关键字.

Note 2: From Swift 5.1, single-line closures don't need the return keyword.

注意 3:尽量不要为自己的类型使用全球知名的名称,例如 Data.至少使用命名空间,例如 MyCustomNameSpace.Data

Note 3: Try not to use globally known names like Data for your own types. At least use namespace for that like MyCustomNameSpace.Data

您可以通过其元素的键路径之一使任何集合可迭代内联:

You can make any collection iterable inline by one of it's element's keypath:

例如self:

List(MyEnum.allCases, id:\.self)

或任何其他兼容的键路径:

or to any other compatible keypath:

List(MyEnum.allCases, id:\.rawValue)


✅ 标识符的清单:(来自 WWDC21)

  • 谨慎使用随机标识符.
  • 使用稳定的标识符.
  • 确保唯一性,每个项目一个标识符.
  • 这篇关于如何在 Swift 中确认对 Identifiable 协议的枚举?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆