Swift编译:变量'self.anInt'在初始化之前被使用-有什么想法吗?

jpfvwuh4  于 2023-04-19  发布在  Swift
关注(0)|答案(2)|浏览(78)

我正在处理一个大型项目,其中一个编译错误突然意外地出现了。这很奇怪,因为它分布在两个完全独立的代码段中,一个触发错误,另一个错误出现。
由于将代码复制到SOF中是不切实际的,所以我设法将其提炼为以下内容,其中在操场上展示了相同的编译器错误:

struct AppConfiguration {
    // Won't compile until this is commented out - ???
    let x = Measurement<UnitMass>(value: 1.0, unit: .kilograms)
}

struct SomeView: View {
    @State var anInt: Int
    // Or THIS is commented out - ???
    let config = AppConfiguration()
    init() {
        anInt = 5   // Compilation error: Variable 'self.anInt' used before being initialized
    }
    var body: some View {
        Text("Hello \(anInt)")
    }
}

其中我们有两个类型:AppConfiguration,它有x:Measurement<UnitMass>值,SomeView,它有一个对配置的引用。

  • 请忽略所有的编码问题,比如我在init()中设置了State变量,并且我实际上没有使用config。正如我所说的,这是展示bug的最简单的代码位,并且它是原始代码,这些事情是出于与此问题无关的其他原因。*

现在,当我在操场上运行这个程序时,我在init()中得到错误**Variable 'self.anInt' used before being initialized**,其中anInt = 5
这是没有意义的,因为这段代码已经好了几个星期了。但是昨天我们把let x = Measurement...行添加到AppConfiguration,现在我们得到了这个错误。

  • 如果我将AppConfiguration中的x的类型更改为Double,则init上的错误将消失。
  • 如果我从SomeView中删除配置并打破依赖关系,错误也会消失。
  • 或者如果我从AppConfiguration中删除x,它也会消失。

所有这些都说不通。
为什么在AppConfiguration中使用Measurement类型会在与之无关的不同类型的代码行上触发编译错误?
有谁能解释一下为什么Measurement以这种方式破坏了编译?

llew8vvj

llew8vvj1#

anInt的类型是State<Int>,所以你需要用这个类型来初始化它。@State Package 器会为你做这件事,但是当你自己做的时候,比如在init()中,你需要使用_anInt
试试这个:

init() { 
    _anInt = State(initialValue: 5) 
}

这是我用来展示我的答案的完整代码。
您也可以删除init()并使用@State var anInt: Int = 5

struct AppConfiguration {
    let x = Measurement<UnitMass>(value: 1.0, unit: .kilograms)
}

struct SomeView: View {
    @State var anInt: Int
    let config = AppConfiguration()
    
    init() {
        _anInt = State(initialValue: 5)  // <-- here
    }
    
    var body: some View {
        Text("Hello \(anInt)")
    }
}

struct ContentView: View {
    var body: some View {
        SomeView()
    }
}
u91tlkcl

u91tlkcl2#

很奇怪。但是我在你的案例中发现了一些有意义的东西。Measurement类型符合ReferenceConvertible协议。有一些类型,例如:

AffineTransform
Calendar
CharacterSet
Data
Date
DateComponents
DateInterval
INMediaDestination
INShortcut
IndexPath
IndexSet
Locale
Measurement
Notification
PersonNameComponents
TimeZone
URL
URLComponents
URLQueryItem
URLRequest
UTType
UUID

我认为编译器需要做一些与@State修饰符相关的事情。建议设置它的默认值或使用底层属性_anInt

struct SomeView: View {
    @State var anInt: Int
    let date = Date()
    
    init() {
        _anInt = State(initialValue: 5) // no error
        // anInt = 5 -> compile error
    }
}

https://developer.apple.com/documentation/foundation/referenceconvertible/

相关问题