[英]why can't my SwiftUI struct be initialised outside the View?
I couldn't get my the below struct to initialise until I moved it into the body of the View.在将下面的结构移入视图主体之前,我无法对其进行初始化。 Can someone explain that to me please?有人可以向我解释一下吗? Thanks!谢谢!
This didn't work:这没有用:
struct ContentView: View {
var sampleText = "This is sample text"
var booksArray = ["Book 1", "Book 2", "Book 3"]
let aBook = Book(passage: sampleText, books: booksArray)
var body: some View {
ScrollView(.vertical, showsIndicators: false, content: {
VStack {
Text(aBook.passage)
.frame(width: 350, height: .infinity, alignment: .center)
.kerning(1)
}
})
}
}
But this did work:但这确实有效:
struct ContentView: View {
var sampleText = "This is sample text"
var booksArray = ["Book 1", "Book 2", "Book 3"]
var body: some View {
let aBook = Book(passage: sampleText, books: booksArray)
ScrollView(.vertical, showsIndicators: false, content: {
VStack {
Text(aBook.passage)
.frame(width: 350, height: .infinity, alignment: .center)
.kerning(1)
}
})
}
}
The error you got from this code reads:您从这段代码中得到的错误是:
cannot use instance member 'sampleText' within property initializer;不能在属性初始值设定项中使用实例成员“sampleText”; property initializers run before 'self' is available属性初始值设定项在“self”可用之前运行
which in plain English means that when aBook
is being assigned, self
, which is the ContentView
is not yet available, so you cannot use sampleText
and booksArray
to initialize aBook
(because it requires all the properties to be initialized - to hold a value).用简单的英语来说,这意味着当aBook
被分配时, self
,即ContentView
尚不可用,因此您不能使用sampleText
和booksArray
来初始化aBook
(因为它需要初始化所有属性 - 以保存一个值)。
You might think, ok then I will use lazy
to initialize aBook
, which means that the assignment of the property will happen after ContentView
has finished the initialization - at first access.你可能会想,好吧,那么我将使用lazy
来初始化aBook
,这意味着属性的分配将在ContentView
完成初始化之后发生——在第一次访问时。
lazy var aBook = Book(passage: sampleText, books: booksArray)
but then a new error appears:但随后出现了一个新错误:
Text(aBook.passage) <= cannot use mutating getter on immutable value: 'self' is immutable Text(aBook.passage) <= 不能对不可变值使用可变 getter:'self' 是不可变的
wait, what?等等,什么? But I'm not trying to mutate it you might say.但你可能会说,我并不是要改变它。
The reality though is that you do mutate ContentView
by accessing aBook
.但现实情况是,您确实通过访问aBook
来改变ContentView
。 Let's illustrate this:让我们来说明一下:
sampleText
is assigned a value sampleText
被赋值booksArray
is assigned a value booksArray
被分配了一个值aBook
is not assigned since is lazy
. aBook
没有分配,因为它很lazy
。 Waits for access in order to be assigned a value.等待访问以分配一个值。ContentView
is initalized ContentView
已初始化aBook
in the body您在正文中访问aBook
aBook
tries to assign a value, but because ContentView
is a struct (value type - immutable) it needs to make a copy of the whole thing. aBook
尝试分配一个值,但是因为ContentView
是一个结构(值类型 - 不可变),所以它需要复制整个东西。 Which is why you get the error这就是你得到错误的原因So, long story short you got a few options:所以,长话短说,你有几个选择:
let aBook = Book(passage: sampleText, books: booksArray)
in the body (as you already mention) let aBook = Book(passage: sampleText, books: booksArray)
在正文中(正如您已经提到的)
A computed property:计算属性:
var aBook: Book { Book(passage: sampleText, books: booksArray) }
or a custom initializer:或自定义初始化程序:
init(sampleText: String, booksArray: [String]) {
self.sampleText = sampleText
self.booksArray = booksArray
self.aBook = Book(passage: sampleText, books: booksArray)
}
or even:甚至:
let sampleText = "This is sample text"
let booksArray = ["Book 1", "Book 2", "Book 3"]
let aBook: Book
init() {
self.aBook = Book(passage: sampleText, books: booksArray)
}
I hope that this makes sense.我希望这是有道理的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.