本文正在参与「金石方案」
前语
最近学习Flutter,发现其运用的Dart言语,有些方面很像Java,有些方面又很像Kotlin,所以整理下目前发现的差异点,一方面便利自己回忆,另一方面也期望能够给尚未触摸过Flutter小伙伴们供给一些协助。(本文仅从Dart言语运用角度对比Java & Kotlin。)
1. 根本数据类型
Dart中,只有三种根本数据类型,数字型(num
),布尔型(bool
),字符串类型(String
)。容器类型如List ,Map,是否归于根本数据类型,这里暂不评论,毕竟运用也很简单。
类型 | Dart | Java | Kotlin |
---|---|---|---|
布尔 | bool | boolean | Boolean |
数字 | num (int / double) | int / double / long / char /byte … | Int / Double /Long / Char / Byte… |
字符串 | String | String | String |
1.1 数字类型
-
num
在Dart 中为抽象类,具有int
及double
两个完成类,运用num
为类型界说变量时,会进行变量类型揣度,揣度为对应的完成类(int
/double
)。///其间需求留意,Dart中num 相同能够作为数据类型运用,如: num a = 10; (整数型) num b = 10.0; (浮点型) int c = 10; (整数型) double d = 10.00; (浮点型)
-
int 类型不只能够表明整形数字,还代表byte 及 char类型数据,详细运用办法如下:
///byte 类型 int x = 65; print(x.toRadixString(2));// 输出 1000001 ///char 类型 List<int> codes = [65, 66]; for(var element in codes) { print(String.fromCharCode(element); //输出 AB }
1.2 字符串类型
-
先看下Dart中字符串的界说,大概与Java 和 Kotlin相同:
字符串界说: ///单引号界说字符串 String e = 'hello world'; String g = '''hello world'''; ///双引号界说字符串 String f = "hello world"; String h = """hello world""";
-
其间运用三引号
'''
与"""
时,会跟随文本换行,而双引号与单引号""
与''
不会,单引号主动换行需求借助\n
换行符。单引号界说的字符串中能够包括双引号,双引号界说的字符串中能够包括单引号, 同类引号中无法包括同类引号,如:错误运用: String a = "----"hello world"----"; String b = '----'hello world'----'; 正确运用: String a = '----"hello world"----'; String b = "----'hello world'----";
-
Dart 支持 Kotlin 字符串拼接办法:
String name = "Child"; String s = "$name, hello world, ${name}"
2.语法差异
Dart的语法与Java根本是相同的,只不过在细节上有些差异,Dart在Java基础上,进行了优化。Dart在Java基础上,进行了优化,使其愈加简洁,便利。
2.1 结构函数
-
Dart中类结构函数写法有许多种,既能够运用与Java彻底相同的写法,也能够运用Dart特有写法,详细写入如下:
Class TestA { int a = 0; int b = 0; ///与Java相同的根本写法 TestA(int a, int b) { this.a = a; this.b = b; } ///Dart 特有结构写法, ///办法1: TestA(this.a, this.b); ///办法2: TestA(int x, int y) : this.a = x, this.b = y; ///办法3:命名结构,与Kotlin中的扩展函数相似,但功用彻底不同。 TestA.instance(this.a, this.b); }
个人感觉,为了便利与Java区分,不建议运用与Java相同的结构写法,而且Dart特有的结构写法,愈加简洁。
2.2 目标操作
-
目标创立:
///Dart中,能够和Java相同相同,运用new关键字立异目标 TestA a = new TestA(); ///相同也能够运用Kotlin办法相同,创立目标 TestA b = TestA(); var c = TestA();
-
目标属性赋值:
///通用赋值办法: TestA object = TestA(); object.x = 10; object.y = 20; ///Dart特有赋值办法: TestA object = TestA() ..x = 10 ..y = 20;
Dart特有的赋值办法看起来有些古怪,但是多看看也就习惯了,留意分号(
;
)在赋值完毕后增加,赋值过程中不需求加。
2.3 空安全
-
Dart 中拥有与Kotlin 相同的变量空安全机制。在界说可为空的变量时,需求在变量后加 ?,示例如下:
class Test { String? x = null; void method() { ///当变量可能为null时,增加问号,检查目标是否为null,不为null时,才会实施 print(x?.length); ///相似Java 三元表达式,Kotlin变量判别是否为null,若为null,则赋予对应值。 String y = x ?? 'hello word'; ///当十分十分十分确认,变量不为null时,能够运用!,强制声明变量肯定不为null print(x!.length); } }
2.4 可变参数
-
Dart具有与Kotlin相同的可变参数的功用,仅仅完成办法有些许不同,示例如下:
class Test() { ///命名参数,required修饰的参数都为必填 void method1({required int a, required int b}) { print('add = ${a + b}'); } ///默认参数,能够为参数赋予默认值,运用时,能够不传入该参数 void method2({required int a, int b = 0}) { print('add = ${a + b}'); } /// 位置参数,其特点是必须按次序依次进行指定若干入参 void method3(int a, [int b = 1, int c = 0]) { print('param: a = ${a}, b = ${b}, c = ${c}'); } void test() { method1(a: 10, b 10); method2(a: 10); method3(10); method3(10, 20); method3(10, 20, 30); } }
3.关键字差异
这里将从Dart与Java不同的关键字,叙述不同的关键字对功用及编码方面的影响。
3.1 可见规模关键字
-
Dart的类,办法,变量只有两种拜访类型,可拜访/不行拜访:
-
在类名,办法名,变量名前增加
_
(下划线),即为外部类不行拜访;没有_
(下划线)为可拜访。 -
没有拜访规模控制关键字,public, private, protect。
class TestB { ///公共变量 int a = 10; ///私有变量,仅能在本类中调用 int _b = 20; ///常量界说, 与Kotlin中界说相同 const c = 30; ///相当于Kotlin的 lateinit,推迟初始化变量 late String d; ///公共办法,能够供内部/外部类调用 void method1() { } ///私有办法,只能在本类调用 void _method2() { var object = _TestC(); } //静态办法,与Java运用办法一致,TestB.method3() 调用 static void method3() { } } ///私有类,拜访规模在本.dart文件中(在TestB类中能够拜访),其他文件中无法拜访 class _TestC { }
3.2 interface & implement 运用差异:
-
Dart中, 没有
interface
接口关键字的界说,但是有implement
。 -
implement
关键字运用,能够完成所有类:抽象类及一般类,需求完成类中所有界说的变量及办法,如下图所示:implement 完成一般类: class BaseA { int x = 10; void method1() { } } class ImplementA implements BaseA { @override int x = 0; @override void method1() { //TODO } }
implement 完成抽象类: abstract class BaseB { final int a = 0; void method1(); void method2() { } } class ImplementB implement BaseB { @override //TODO int get a => 0; @overide void method1() { //TODO } @override void method2() { //TODO } }
-
与Java & Kotlin相同,一个类能够完成多个(接口)类。
-
接口二义性问题处理:当 C 类完成 A 、B 接口,会强制重写所有办法,成员变量供给
get
办法;即在当时类,办法只具有一种完成,变量值需从头赋值,这样就处理了二义性问题。示例如下:class C implement A, B { @override String str = 'hello world'; @override void go() { //TODO } }
3.3 with & mixin 混入
-
意义:
with
&mixin
为Dart完成混入(mixins)的关键字,混入是指将一个类的代码插入到另一个类中,以增强该类的功用,而不需求创立一个新的子类。 -
效果:完成类功用扩展(能够一起混入多个)。比如Java & Kotlin 能够经过内部类的方式,来扩展类功用。
-
与一般类差异:混入类,没有结构办法,无法实例化。
-
与接口差异:接口只界说一类功用接口,没有完好功用完成;混入类需具有完好功用完成。
///混入类界说 mixin Write { final String word = 'hello world'; void write() { print('person can write: $word'); } } ///一般类接入混入类,引进混入类完成功用 class Person with Write { @override String get word => 'hello word! ++'; } class Test { void method() { Person p = Person(); p.write(); } }
混入类功用与接口相似,所以相同存在二义性问题,那么混入类是怎么处理二义性问题的呢?
- 如C 以先A ,后B次序混入两个类,A, B 中都含有一个变量名name的字符串,混入C后,打印字符串name,显现的为后混入B类中name的值。 即混入多个类时,若界说的相同类型&相同称号的变量,值为最终混入的类的值。
- 若变量名相同,但变量类型不同,一起混入会报错。
3.4 extension 拓宽/扩展办法
-
这个功用与Kotlin的扩展办法是相似的,都能够在不修正类文件的前提下,扩展类办法。
-
Kotlin不只能够增加扩展办法,一起能够增加扩展变量。Dart只能够增加拓宽办法。
extension StringUtil on String { bool isNullorEmpty(String? str) { return str == null || str.isEmpty; } }
3.5 on 关键字。
-
on
关键字用于混入类间,完成相似extends
的关系。即混入类能够经过on
关键字引进其他类的功用。需求留意的是,混入类不只能够引进混入类,也能够引进一般类与抽象类。例如:mixin D { String d = 'hello word! D'; void run() { print('on keyword --- ${d}') } } mixin E on D { @override set(String value) { d = value; } @override void run() { super.run(); } }
-
on
与extension
合作运用,表明对哪个类进行扩展。
3.6 switch 关键字
-
switch
关键字与Java中的功用相同,即判别履行分支。其间有一个需求留意的细节,Dart中,目标类型也能够作为分支判别条件。class Test { void method1() { Person p1 = Person(); Person p2 = Person(); Person p3 = Person(); Person p = p1; switch(p) { case p1: //TODO break; case p2: //TODO break; case p3: //TODO break; } } }
-
Java中,判别目标只能为根本数据类型,如下图所示。
3.7 set & get 关键字
-
与Kotlin相似,Dart供给了
set
&get
关键字,完成变量的setter
&getter
功用。示例如下:class Test { void method() { A a = A(); print(' get value : ${a.getValue}'); a.setValue(10); print(' get value : ${a.getValue}'); } } class A { int _value = 0; int get getValue => _value; /// => 是Dart中的省掉写法,完好办法如下: int get getValue { return _value; } set setValue(int value) { _value = value; } }
3.8 Function 函数目标
-
界说:函数目标与Kotlin的高阶函数相似,能够理解为函数目标类型的关键字;指定传入参数,履行对应代码块后,回来指定类型的回来值。这也是Dart 比 Java 更接近万物皆目标的体现。
-
效果:与Kotlin的高阶函数功用一致,界说一类功用的完成规则。示例如下:
typedef Operate = int Function(int, int); class Test { void method() { Operate add = (a, b) { return a + b; } add.call(10, 20) } }
总结
总的来说,Dart言语与Java&Kotlin许多相似的当地,在最开始学习时,记住不同点,编码方面就不会有太多的阻止。但是从言语规划层面看,Dart与Java&Kotlin还是有很大的差异,等我悟道之后,再和大家细说。 如果有需求完善,或者不认同的当地,欢迎大家留言评论。
本文正在参与「金石方案」