package a public struct Rectangle { public var width: Int64 var height: Int64 private var area: Int64 ... }
func samePkgFunc() { var r = Rectangle(10, 20) r.width = 8 // Ok: public 'width' can be accessed here r.height = 24 // Ok: 'height' has no modifier and can be accessed here r.area = 30 // Error, private 'area' can't be accessed here } package b import a.* main() { var r = Rectangle(10, 20) r.width = 8 // Ok: public 'width' can be accessed here r.height = 24 // Error, no modifier 'height' can't be accessed here r.area = 30 // Error, private 'area' can't be accessed here }
public func area() { width * height } } let r = Rectangle(10, 20) let width = r.width // width = 10 let height = r.height // height = 20 let a = r.area() // a = 200
如果希望通过 struct 实例去修改成员变量的值,需要将 struct 类型的变量定义为可变变量,并且被修改的成员变量也必须是可变成员变量(使用 var 定义)。举例如下:
struct A { public mut func f(): Unit {} // Ok public mut operator func +(rhs: A): A { // Ok A() } public mut static func g(): Unit {} // Error, static member functions cannot be modified with 'mut' }
mut 函数中的 this 不能被捕获,也不能作为表达式。mut 函数中的 lambda 或嵌套函数不能对 struct 的实例成员变量进行捕获。
示例:
1 2 3 4 5 6 7 8 9 10 11
struct Foo { var i = 0
public mut func f(): Foo { let f1 = { => this } // Error, 'this' in mut functions cannot be captured let f2 = { => this.i = 2 } // Error, instance member variables in mut functions cannot be captured let f3 = { => this.i } // Error, instance member variables in mut functions cannot be captured let f4 = { => i } // Error, instance member variables in mut functions cannot be captured this // Error, 'this' in mut functions cannot be used as expressions } }
interface I { mut func f1(): Unit func f2(): Unit }
struct A <: I { public mut func f1(): Unit {} // Ok: as in the interface, the 'mut' modifier is used public func f2(): Unit {} // Ok: as in the interface, the 'mut' modifier is not used }
struct B <: I { public func f1(): Unit {} // Error, 'f1' is modified with 'mut' in interface, but not in struct public mut func f2(): Unit {} // Error, 'f2' is not modified with 'mut' in interface, but did in struct }
class C <: I { public func f1(): Unit {} // Ok public func f2(): Unit {} // Ok }
interface I { mut func f(): Unit } struct Foo <: I { public var v = 0 public mut func f(): Unit { v += 1 } } main() { var a = Foo() var b: I = a b.f() // Calling 'f' via 'b' cannot modify the value of 'a' println(a.v) // 0 }
因为 struct 是值类型,所以如果一个变量是 struct 类型且使用 let 声明,那么不能通过这个变量访问该类型的 mut 函数。
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
interface I { mut func f(): Unit } struct Foo <: I { public var i = 0 public mut func f(): Unit { i += 1 } } main() { let a = Foo() a.f() // Error, 'a' is of type struct and is declared with 'let', the 'mut' function cannot be accessed via 'a' var b = Foo() b.f() // Ok let c: I = Foo() c.f() // Ok, 变量 c 为接口 I 类型,非 struct 类型,此处允许访问。 }