You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftData中枚举属性设默认值引发编译错误,该如何修复?

SwiftData枚举属性默认值编译错误的修复方案

说明:

  • 本问题最初发布于Xcode 15测试版期间。在Xcode 15正式版中,编译器给出的错误提示更为清晰:

A default value requires a fully qualified domain named value


原始问题:
我把问题简化为一个带枚举属性的简单模型类,尝试给这个属性设置默认值时,代码无法编译:

enum SomeEnum: Hashable, Codable {
    case one
    case two
}

@Model
class SomeClass {
    var value: SomeEnum = .two

    init() {
    }
}

编译后会出现如下错误:

type 'Any?' has no member 'two'

查看详细日志能看到更多信息:

@__swiftmacro_8Sample39SomeClass5ModelfMm_.swift:15:34: error: type 'Any?' has no member 'two'
    ("value", \SomeClass.value, .two, nil)
                                ~^~~
/.../Sample.swift:117:1: note: in expansion of macro 'Model' here
class SomeClass {
^~~~~~~~~~~~~~~~~
/.../Sample.swift:117:1: note: in expansion of macro 'Model' here
class SomeClass {
^~~~~~~~~~~~~~~~~

右键点击@Model选择“Expand Macro”(展开宏)后,能看到宏生成的代码:

@Model
class SomeClass {
    var value: SomeEnum = .two

    init() {
    }

    @Transient
    private var _$backingData: any SwiftData.BackingData<SomeClass> = SwiftData.DefaultBackingData(for: SomeClass.self)
    
    public var backingData: any SwiftData.BackingData<SomeClass> {
        get {
            _$backingData
        }
        set {
            _$backingData = newValue
        }
    }
    
    static func schemaMetadata() -> [(String, AnyKeyPath, Any?, Any?)] {
      return [
        ("value", \SomeClass.value, .two, nil) // <-- 错误位置
      ]
    }
    
    required init(backingData: any SwiftData.BackingData<SomeClass>) {
      self.backingData = backingData
    }
    
    @Transient
    private let _$observationRegistrar = Observation.ObservationRegistrar()

}

错误明显来自schemaMetadata()函数内部。

修复方法

问题根源是SwiftData宏展开时,无法正确推断简写形式.two的枚举类型。解决办法很简单,使用完全限定的枚举值指定默认值,把.two替换成SomeEnum.two即可:

修改后的代码:

enum SomeEnum: Hashable, Codable {
    case one
    case two
}

@Model
class SomeClass {
    var value: SomeEnum = SomeEnum.two

    init() {
    }
}

这样修改后,宏生成的schemaMetadata()函数能正确识别枚举值的类型,编译错误就会消失。原因是宏生成的代码里,默认值被放在Any?类型的位置,简写枚举值无法被编译器正确解析,而完全限定名能明确告知编译器具体的枚举类型和对应值。

内容的提问来源于stack exchange,提问作者HangarRash

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 04:40:37