当前位置:   article > 正文

仓颉编程语言开发:mut 函数

仓颉编程语言开发:mut 函数

struct 类型是值类型,其实例成员函数无法修改实例本身。例如,下例中,成员函数 g 中不能修改成员变量 i 的值。

  1. struct Foo {
  2. var i = 0
  3. public func g() {
  4. i += 1 // Error, the value of a instance member variable cannot be modified in an instance member function
  5. }
  6. }

mut 函数是一种可以修改 struct 实例本身的特殊的实例成员函数。在 mut 函数内部,this 的语义是特殊的,这种 this 拥有原地修改字段的能力。

注意

只允许在 interface、struct 和 struct 的扩展内定义 mut 函数(class 是引用类型,实例成员函数不需要加 mut 也可以修改实例成员变量,所以禁止在 class 中定义 mut 函数)。

mut 函数定义

mut 函数与普通的实例成员函数相比,多一个 mut 关键字来修饰。

例如,下例中在函数 g 之前增加 mut 修饰符之后,即可在函数体内修改成员变量 i 的值。

  1. struct Foo {
  2. var i = 0
  3. public mut func g() {
  4. i += 1 // ok
  5. }
  6. }

mut 只能修饰实例成员函数,不能修饰静态成员函数。

  1. struct A {
  2. public mut func f(): Unit {} // ok
  3. public mut operator func +(rhs: A): A { // ok
  4. A()
  5. }
  6. public mut static func g(): Unit {} // Error, static member functions cannot be modified with 'mut'
  7. }

mut 函数中的 this 不能被捕获,也不能作为表达式。不能在 mut 函数中对 struct 的实例成员变量进行捕获。

示例:

  1. struct Foo {
  2. var i = 0
  3. public mut func f(): Foo {
  4. let f1 = { => this } // Error, 'this' in mut functions cannot be captured
  5. let f2 = { => this.i = 2 } // Error, instance member variables in mut functions cannot be captured
  6. let f3 = { => this.i } // Error, instance member variables in mut functions cannot be captured
  7. let f4 = { => i } // Error, instance member variables in mut functions cannot be captured
  8. this // Error, 'this' in mut functions cannot be used as expressions
  9. }
  10. }

接口中的 mut 函数

接口中的实例成员函数,也可以使用 mut 修饰。

struct 类型在实现 interface 的函数时必须保持一样的 mut 修饰。struct 以外的类型实现 interface 的函数时不能使用 mut 修饰。

示例:

  1. interface I {
  2. mut func f1(): Unit
  3. func f2(): Unit
  4. }
  5. struct A <: I {
  6. public mut func f1(): Unit {} // Ok: as in the interface, the 'mut' modifier is used
  7. public func f2(): Unit {} // Ok: as in the interface, the 'mut' modifier is not used
  8. }
  9. struct B <: I {
  10. public func f1(): Unit {} // Error, 'f1' is modified with 'mut' in interface, but not in struct
  11. public mut func f2(): Unit {} // Error, 'f2' is not modified with 'mut' in interface, but did in struct
  12. }
  13. class C <: I {
  14. public func f1(): Unit {} // ok
  15. public func f2(): Unit {} // ok
  16. }

当 struct 的实例赋值给 interface 类型时是拷贝语义,因此 interface 的 mut 函数并不能修改 struct 实例的值。

示例:

  1. interface I {
  2. mut func f(): Unit
  3. }
  4. struct Foo <: I {
  5. public var v = 0
  6. public mut func f(): Unit {
  7. v += 1
  8. }
  9. }
  10. main() {
  11. var a = Foo()
  12. var b: I = a
  13. b.f() // Calling 'f' via 'b' cannot modify the value of 'a'
  14. println(a.v) // 0
  15. }

程序输出结果为:

0

mut 函数的使用限制

因为 struct 是值类型,所以如果一个变量是 struct 类型且使用 let 声明,那么不能通过这个变量访问该类型的 mut 函数。

示例:

  1. interface I {
  2. mut func f(): Unit
  3. }
  4. struct Foo <: I {
  5. public var i = 0
  6. public mut func f(): Unit {
  7. i += 1
  8. }
  9. }
  10. main() {
  11. let a = Foo()
  12. a.f() // Error, 'a' is of type struct and is declared with 'let', the 'mut' function cannot be accessed via 'a'
  13. var b = Foo()
  14. b.f() // ok
  15. let c: I = Foo()
  16. c.f() // ok
  17. }

为避免逃逸,如果一个变量的类型是 struct 类型,那么这个变量不能将该类型使用 mut 修饰的函数作为一等公民来使用,只能调用这些 mut 函数。

示例:

  1. interface I {
  2. mut func f(): Unit
  3. }
  4. struct Foo <: I {
  5. var i = 0
  6. public mut func f(): Unit {
  7. i += 1
  8. }
  9. }
  10. main() {
  11. var a = Foo()
  12. var fn = a.f // Error, mut function 'f' of 'a' cannot be used as a first class citizen.
  13. var b: I = Foo()
  14. fn = b.f // ok
  15. }

为避免逃逸,非 mut 的实例成员函数(包括 lambda 表达式)不能直接访问所在类型的 mut 函数,反之可以。

示例:

  1. struct Foo {
  2. var i = 0
  3. public mut func f(): Unit {
  4. i += 1
  5. g() // ok
  6. }
  7. public func g(): Unit {
  8. f() // Error, mut functions cannot be invoked in non-mut functions
  9. }
  10. }
  11. interface I {
  12. mut func f(): Unit {
  13. g() // ok
  14. }
  15. func g(): Unit {
  16. f() // Error, mut functions cannot be invoked in non-mut functions
  17. }
  18. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/1009824
推荐阅读
相关标签
  

闽ICP备14008679号