为什么这会显示“实例方法声明中的预期 'func' 关键字”

Why is this showing 'Expected 'func' keyword in instance method declaration'

我是在 Xcode 上编码和使用 SwiftUI 的新手,我看不出这段代码有什么问题:

class NormalSpace {
    var name = ""
    var value = 0
    var rent = 0
    var owned = false
}

var newRoad = NormalSpace()

newRoad.name = "New Road"
newRoad.value = 600
newRoad.rent = 25
newRoad.owned = false

错误“实例方法声明中需要 'func' 关键字”仅显示在 newRoad.name 行。同一行还有错误:Invalid redeclaration of 'newRoad'.

我做错了什么?

在正常项目中,这是无效的:

class NormalSpace {
    var name = ""
    var value = 0
    var rent = 0
    var owned = false
}

var newRoad = NormalSpace()

newRoad.name = "New Road"
newRoad.value = 600
newRoad.rent = 25
newRoad.owned = false

您可以在 playground 中执行此操作(直接 运行 编写此代码),但在应用程序中,代码(例如属性设置)属于函数或初始化程序。

该初始化代码需要放在某些上下文中。让我们想象它在 struct 中。但这仍然无效:

class NormalSpace {
    var name = ""
    var value = 0
    var rent = 0
    var owned = false
}

struct Foo {
    var newRoad = NormalSpace()
    
    newRoad.name = "New Road"
    newRoad.value = 600
    newRoad.rent = 25
    newRoad.owned = false
}

属性、newRoad可以,但数值不行。您需要将其包装在 func(因此出现错误)或 init 中。例如,这会在 struct:

init 期间初始化 newRoad
struct Foo {
    let newRoad: NormalSpace
    
    init() {
        newRoad = NormalSpace()

        newRoad.name = "New Road"
        newRoad.value = 600
        newRoad.rent = 25
        newRoad.owned = false
    }
}

或者您可以在 func:

中初始化它
struct Foo {
    var newRoad: NormalSpace?

    mutating func bar() {
        let road = NormalSpace()

        road.name = "New Road"
        road.value = 600
        road.rent = 25
        road.owned = false

        newRoad = road
    }
}

或者,您可以用闭包初始化此 属性(注意末尾的额外 ()):

struct Foo {
    let newRoad: NormalSpace = {
        let road = NormalSpace()
        road.name = "New Road"
        road.value = 600
        road.rent = 25
        road.owned = false
        return road
    }()
}

但是初始化属性的代码必须放在某个上下文中,以便编译器知道这些代码行何时应该 运行。


注意,我们通常会给 NormalSpace 一个“memberwise initializer”,例如:

class NormalSpace {
    let name: String
    let value: Int
    let rent: Int
    let owned: Bool

    init(name: String, value: Int, rent: Int, owned: Bool) {
        self.name = name
        self.value = value
        self.rent = rent
        self.owned = owned
    }
}

或者,如果 struct(我们通常更愿意将我们的模型对象设为 struct value-types 而不是 class reference-types),这将为您创建成员初始化器:

struct NormalSpace {
    let name: String
    let value: Int
    let rent: Int
    let owned: Bool
}

无论哪种方式,您都可以在初始化期间提供所有需要的值,例如:

struct Foo {
    let newRoad = NormalSpace(name: "New Road", value: 600, rent: 25, owned: false)
}

请注意,我删除了“默认”值,因为它们确实不合适。如果您想说不需要提供它们,那么您可以将它们设为“可选”。但是,例如,零租金(即这是我祖母的房子,她没有向我收费)和没有指定租金之间通常存在很大差异。在 Swift 中,我们通常避免使用 ""0 等“标记”值来表示“未提供任何值”。

此外,既然我们有了一个成员初始化器,我也使属性不可变(let 而不是 var)。如果你需要让它们可变(例如让别人稍后改变租金),很好,恢复到 var。但是只有在您以后确实需要更改属性时才将它们设为可变。