面向Kotlin与Java开发者的Dart快速入门(一)变量

在这里插入图片描述

变量/函数的作用域


与Kotlin一样,Dart可以在top-level进行变量或函数声明,main函数也在top-level声明,相对于Java作用域变得更广。

Dart中万物皆对象,所有的函数本质上都是Function类型的实例变量,所以函数可以像变量一样出现在top-level。


动态类型


Dart并非脚本语言,所以这里的“动态类型”是指Java的Object或者Kotlin的Any那样的不确定类型,可以在运行时强转成任何具体类型使用。Dart使用Object或者dynamic声明这种不确定类型。

dynamicObject非常相近,都可以动态进行类型检查、动态赋任何类型的值

/// 动态判断dynamic对象
bool convertToBool(dynamic arg) {
  if (arg is bool) return arg;
  if (arg is String) return arg == 'true';
  throw ArgumentError('Cannot convert $arg to a bool.');
}

他们的区别主要在与静态检查上:

  • dynamic:编译器不会对dynamic象进行静态检查,dynamic对象的任何操作在编译期都是合法的,但是运行时是否会出错需要开发者自己保证,所以建议大家在编程时不要不过度使用dynamic。
  • Object: 是Dart对象的基类,当你定义Object o = xxx ;时 ,编译器会将o作为一个Object对象看待,可以以调用otoString()hashCode()方法,因为Object 提供了这些方法,但是如果你尝试调用o.foo()时,静态类型检查会运行报错。

Object就是Java的Object,dynamic更像是Javascript的var。有趣的是Dart也有var关键字,但是Dart的var与Js的var不同,一旦赋值之后类型就不能再改变了,所以Dart的var更像是Kotlin的var

根据 Effective Dart 的建议:

  • 当实例代表“任何类型”时,使用Object
  • 当实例代表“某种待定类型时”时,使用dynamic,可能在某个时间点确定

访问控制


通过在函数、变量、类之前添加前导下划线(_)表示其私有性,类似于Java的private关键字,看起来像是借鉴了python的语法。

需要注意这里的私有不是指package的私有,而是library的私有。library内部即使添加了前导下划线也是可以互相访问的,例如一个Class内的_函数仍然可以被Class外部访问,library内部的访问控制需要使用linter关键字


类型推导


Dart像Kotlin一样,可以根据上线文推断出变量类型,而不必事先显式地进行类型声明

var hoge = "huga";
[1, 2, 3].forEach((x) => print(x*2));

Dart能够推断出hoge是String,x是int
主要注意,当指定类型声明时,类型需要像Java前置声明,而不是像Kotlin一样后置。


变量默认值


  • Dart中万物皆对象,都继承自Object,所以默认值都是null,包括intdouble
  • Java中存在非对象的基本型,所以默认值不是null
  • Kotlin的基本型虽然本质上也是对象,但是其默认值并不是null

使用assert进行判空

因为Dart的默认值null的存在,写代码时需要注意判空。Dart的assert()不会影响生产环境中代码的执行,它仅仅在测试环境中起作用,实际开发中可以活用assert进行判空。

Dart 2.7引入了NNBD (Non null by default),可以像Kotlin一样声明非空类型,将NPE扑灭在编译期。


NNBD


从 2.7 开始Dart像Kotlin一样允许声明非空类型

// int是non-null类型
final int a = 1;

// non-null类型赋值null会出现error
final int b = null;

// int?是nullable类型,可以赋值null
final int? c = null;

我们在命名参数前加required关键字,表示此参数一定能取到值

// arg1 :non-null的String类型
void doSomething({required String arg1}) { ... }

// 调用函数时,required的参数不可省略
doSomething(arg1: "hoge");

可以在flutter项目根目录创建一个analysis_options.yaml文件,然后通过添加以下内容,对空安全进行静态检查

analyzer:
  enable-experiment:     
    - non-nullable

不可变类型与常量


final

类似于Java的final或者Kotlin的val,使用final声明的变量是不可变的,不能被二次赋值。

final hoge = "fuga";

虽然与Java的用法相近,但是细节上更严格:

  • Java的final只规定不能二次赋值,但是没有规定初始化的时机
  • Dart的final要求必须在声明的同时或者在初始化列表中完成初始化。

Class的final成员可以在初始化列表中初始化:

mport 'dart:math';

class Point {
  final num x;
  final num y;
  final num distanceFromOrigin;

  Point(x, y)
      : x = x, //初始化列表中对final成员初始化
        y = y,
        distanceFromOrigin = sqrt(x * x + y * y);
}

main() {
  var p = new Point(2, 3);
  print(p.distanceFromOrigin);
}

const

  • const是编译期必须确定的常量,相当于Kotlin的const val x
  • final是可以在运行时在进行第一次初始化:
final x = new DateTime.now(); // 正确
const x = new DateTime.now(); // 错误

final y = sin(90); // 正确
const y = sin(90); // 错误

另外,const还可以进行字面值的list创建:

var hoge = const [1, 2, 3];

此时hoge是一个immutable的list,内部的item不能变更



返回首页:Dart入门教程

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

fundroid

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值