首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果我在if语句中使用'is‘关键字,那么Dart Upcast是如何自动转换的

如果我在if语句中使用'is‘关键字,那么Dart Upcast是如何自动转换的
EN

Stack Overflow用户
提问于 2021-06-21 08:10:23
回答 2查看 85关注 0票数 0

这是我的课,

代码语言:javascript
复制
class Animal{
  Animal();
}
class Mammal extends Animal{
  String name;
  Mammal(this.name):super();
}

在我的主要方法里,

代码语言:javascript
复制
main() {
    Animal dog = new Mammal("Tommy");
    if(dog is Mammal)
        print(dog.name); //prints "Tommy"
}

我的狗对象有动物类型,它怎么能暴露哺乳动物的财产“名字”?Dartpad本身就是自动的--建议我使用“name”属性。

威尔,它从动物类型上升到哺乳动物,因为我确信狗对象是哺乳动物,一旦它进入if语句。但在幕后是如何运作的呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-06-21 15:16:54

您所描述的特性称为“类型提升”,它只发生在编译器能够证明它有效的地方。

例如:

  • 函数参数:

代码语言:javascript
复制
void function(Animal animal) {
  if (animal is Mammal) {
    // animal now has a static type of Mammal
    print(animal.name); // safe to access Mammal-only fields
  }
}

  • 局部变量:

代码语言:javascript
复制
void function() {
  Animal animal = Mammal('name');
  if (animal is Mammal) {
    // animal now has a static type of Mammal
  }
}

但是,它不适用于:

  • 顶级字段

代码语言:javascript
复制
Animal animal = Mammal('name');

void function() {
  if (animal is Mammal) {
    // animal still has static type Animal
  }
}

  • 或实例字段

代码语言:javascript
复制
class Foo {
  Animal animal;

  void function() {
    if (animal is Animal) {
      // animal still has a static type of Animal
    }
  }
}

这是因为Dart的getter语法。在Dart中,可以使用以下语法定义getter:

代码语言:javascript
复制
Foo get foo {
  return makeSomeFoo();
}

事实上,尽管大多数人认为“getter是类似于字段的函数”,但实际上恰恰相反:字段自动生成相应的getter。这意味着类型提升不能用于任何字段访问在概念上可能是getter的地方。

因为局部变量和函数参数没有“覆盖getter”的概念,所以它们是安全的。

但是,想象一下下面的顶级getter:

代码语言:javascript
复制
Animal get animal {
  if (Random().nextBool()) return Mammal('name');
  else return Reptile('name');
}

仅仅因为对animal的第一个调用返回了一个Mammal,并不意味着后续的调用总是会这样,所以假设animal现在是一个Mammal是不安全的。

类似的逻辑适用于类,并增加了getter可以覆盖字段的复杂性。

注意,通过使用局部变量,可以轻松地解决实例成员和顶级getter的问题:

代码语言:javascript
复制
Animal get animal => // some implementation

void function() {
  final _animal = animal;
  if (_animal is Animal) {
    print(_animal.name);  // totally safe
  }
}
票数 1
EN

Stack Overflow用户

发布于 2021-06-21 08:30:19

我找到了答案,这就是所谓的智能铸造。Dart可以自动对局部变量进行转换,如果它在保证变量类型的条件语句中。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68064529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档