首页 > 解决方案 > Dart:为什么类方法使用 this.variableName 或 variableName 的工作方式相同?

问题描述

我想知道它是否被有意设计为能够使用两种不同的方式来编写类方法,其中引用了一个实例属性,这听起来可能很模糊,所以我提供了一个小代码片段来说明我的观点。

起初,我的印象是我们使用this.age而不是age因为后者会修改所有实例age属性,但是当我尝试使用 & 而不使用this.关键字时,它只更改了changeAge使用该方法的实例。

有两种写法的目的吗?

class Person{
  String name;
  int age;
  Person({this.name, this.age});
  
  void changeAge(int a){
    this.age = a; // why can this be written: age = a; and achieve same result?
  }
  }
void main(){
  Person foo = Person(name: 'foo', age: 16);
  Person bar = Person(name: 'bar', age: 30);
  foo.changeAge(99);
  print(foo.age); // prints 99
  print(bar.age); // prints 30 
}

标签: dart

解决方案


Dart 使用词法作用域来查找标识符的含义。编写age时,编译器:

  1. 首先检查当前函数中是否存在局部变量名age
  2. 然后它检查是否存在名为 的周围函数的参数或类型参数age
  3. 然后它检查是否有age在周围类中命名的声明(在 中Person)。这可以是实例声明或静态声明。
  4. 然后它检查名为 的类的类型参数age,如果该类是泛型的。
  5. 然后它检查当前库是否有一个名为age.
  6. 然后它检查一个名为age.

如果它找到任何声明,则它认为age是指该声明。如果它找到的是一个静态声明,那么age就等价于ClassName.age. 如果它找到了一个实例声明,则age等价于this.age.

如果它什么也没找到,并且它在一个实例方法中,那么它会age被视为this.age,如果当前类中没有继承age的实例成员,则它是一个错误。

所以,在这种情况下,原因age = a;this.age = a;相同是age解析为周围类的实例变量。

不必写this.age,但你可以,这就是为什么你可以把你的changeAge方法写成:

  void changeAge(int age){
    this.age = age; // `this.age` is the field, `age` refers to the parameter.
  }

推荐阅读