一个最基础的Dart程序
1 2 3 4 5 6 7 8 9 10 11 printInterger(int aNumber, int bNumber) { print ('the number is $aNumber and ${bNumber} ' ); } main() var number = 42 ; printInterger(number); }
重要概念:
所有变量都可以看成是一个object
,所有的object
都是通过Object
class实例化出来的。这点和js一样
Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用dynamic
类型。如- Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用`dynamic`类型。如
- Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用dynamic
类型。如``- Dart是强类型语言,累心注释是可选的,因为Dart可以推断类型,如果想要定义一个没有类型的可以使用dynamic
类型。如var list= <dynamic>[1]
Dart的私有方法,都是以_
下划线开头的,不像java直接写关键字private
.
变量 声明变量 1 2 3 4 5 6 var name = 'Bob' ;dynamic name2 = 'Bob' ;String name3 = 'Bob' ;
变量默认值 和js
不一样的是,如果在Dart
里面声明一个变量,但是不赋值的话,他的默认值是null
而不是undefined
.
这也从另一个角度说明在Dart
中,万物皆对象.
1 2 3 4 int lineCount;var line;assert (lineCount == null );assert (line == null );
final && const Dart
里面的常量用 final
和const
声明。
final
表示单个赋值,一旦赋值,就不能被改变。const
表示编译时确定的值,并且对象会被冻结而完全不可变。
stackoverflow
1 2 const a = 1 +2 ;final b = DateTime .now();
内置类型
numbers
strings
booleans
lists(Array)
sets
maps
runes (Unicode characters in a string)
symbols
可以通过x.runtimeType
来获取对象的类型
number Dart的number有两种类型: int
和 double
简单的区分,小的整数用int
,浮点数用double
。一般直接用var
声明的话,会根据你声明时的类型做推断,所以如果声明和后面使用不一样的话,建议显式声明.例
1 2 3 4 5 6 var x = 1 ; x = 2.0 ; var x = 1.0 ; double x = 1 ;
字符串转数字 在Dart里面,如果字符串和数字相加,会报错,这一点和js隐式转换不同。
1 2 3 4 var one = int .parse('1' ); var onePointOne = double .parse('1.1' ); String oneAsString = 1. toString(); String piAsString = 3.141592654 .toStringAsFixed(2 );
Strings 可以用'
或"
来表示字符串。
字符串内部的变量可以用$value
或者${value}
,一般来说如果是变量,直接用$value
表示,表达式用${value}
,例:
1 2 3 var a = 'String1' ;var b = "String2" ;assert ('String1 STRING2' == '$a ${b.toUpperCase()} ' );
如果要创建多行的字符串,则可以用'''
或"""
,
1 2 3 4 5 var s1 = ''' hi I'm Jsonz ''' var s2 = '
Booleans Dart
里面if
与assert
都只会对 bool
做判断,这点同样与js的隐式转换不同。
1 2 3 4 5 6 7 8 9 var fullName = '' ;assert (fullName); assert (fullName.isEmpty); var hitPoints = 0 ;assert (hitPoints <= 0 );var iMeantToDoThis = 0 / 0 ;assert (iMeantToDoThis.isNaN);
Lists (既js里面的数组) 1 2 3 4 5 6 7 8 9 10 11 12 13 var list = [1 ,2 ,3 , '4' ]; var typeList = <int >[1 ,2 ,3 ]; assert (list.length == 4 );typeList[0 ] = 2 ; assert (typeList[0 ] == 2 );var constantList = const [1 ,2 ,3 ];constantList[1 ] = 1 ; List <int > list = const [1 ,2 ,3 ];
Sets Sets
会根据初始化推断类型,比如下面的例子halogens
会判断为String
类型,这时候添加其他类型的值就会报错。
1 2 3 4 5 6 7 var halogens = {'fluorine' , 'chlorine' , 'bromine' , 'iodine' , 'astatine' };halogens.add(1 ); var name = {}; var names = <String >{}; Set <String > name2 = {};
Set
通过add
或者addAll
添加item
。 可以通过const
关键字创建编译常量
1 2 3 4 5 6 7 8 9 10 11 12 var el = <String >{};var el2 = {'a' , 'b' };el.add('c' ); el.addAll(el2); assert (el.length == 3 );final constantSet = const { 'a' , 'b' , }
Maps(相当于js的对象) Dart
的Map
不限制key
的类型,意味着如果是number
类型,不需要和js
一样,用[]
包着。
Map
也会推断key
和value
的类型,比如下面的 map1
就是key
为int
类型,value
为string
类型的map
.
如果获取某个map
没有的value
,则value
默认是null
。这点和js
的undefined
不同,可以对比变量初始化的情况类推。
map
也有length
属性,类比js
的Object.keys(obj).length
.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 var gif = { 'a' : 'b' , 1 : 2 , 3 : '4' , } var map1 = { 1 : '2' , } final constantMap = const { 2 : '2' , } constantMap[2 ] = '3' ;
Runes emmm 这个我的理解是UTF-32编码的字符串,简单理解就是可以支持更多类型的字符串,比如emoji,工作用到再去查。 比如'\u{1f44f}';
是👏
,\u2665
是♥
。
Symbols (类比js的Symbol) 对Symbol
的理解可以直接看阮一峰的ES6-Symbol ,基本的作用是一样的。
Dart
的Symbol
是compoile-time constants
,就是编译时常量。 使用也很简单,直接在标识前面加个#
Function Dart是面向对象的语言,所以函数也是一种Function
类型的对象。
参数的默认值都为null
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 bool isNaN(int number) { return number.isNaN; } isNaN2(number) { return number.isNaN; } bool isNaN3(int number)=> number.isNaN;void enableFlags({ bool bold, bool hidden }) { print (bold); print (hidden); } enableFlags(bold: true , hidden: false ); enableFlags(hidden: false , bold: true ); enableFlags(hidden: false ); void enableFlags2(bool bold, bool hidden, [String device]) { } enableFlags2(true , false , 'device' ); void enableFlags({ bool bold= false , bool hidden= false , }) {} enableFlags(hidden: true ); void doStuff({ List <int > list = const [1 ,2 ,3 ], Map <String , String > gifts = const { 'first' : 'paper' , 'second' : 'cotton' , 'third' : 'leather' } }) { print ('list: $list ' ); print ('gifts: $gifts ' ); }
main 函数 每个app都需要在最顶层提供一个main
函数用于入口函数,main
函数提供一个void返回值与List<String>
参数(参数指的是命令行传入的参数)。
函数为第一公民 和js一样,Dart也支持将函数作为参数传给另一个函数(高阶函数)。
1 2 3 4 5 6 void printE(int e) { print (e); } var list = [1 ,2 ,3 ];list.forEach(printE);
匿名函数、作用域与闭包 这几个和js是一样的,没啥好说
对词法作用域和动态作用域有疑问的可以看这篇
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 var list = [1 ,2 ,3 ];list.forEach((item)=> print (item)); list.forEach((item) {print (item);}); a() { var a1 = true ; b() { var b1 = true ; c() { var c1 = true ; assert (a1); assert (b1); assert (c1); } } } Function makeAdder(num addBy) { return (num i) => addBy + i; } void main() { var add2 = makeAdder(2 ); var add4 = makeAdder(4 ); assert (add2(3 ) == 5 ); assert (add4(3 ) == 7 ); }
函数类型(Testing functions for equality) 看着自己理解一下就好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 void foo() {} class A { static void bar() {} void baz() {} } void main() { var x; x = foo; assert (foo == x); x = A.bar; assert (A.bar == x); var v = A(); var w = A(); var y = w; x = w.baz; assert (y.baz == x); assert (v.baz != w.baz); }
函数返回值 函数都会返回一个值,如果没有指定的话,则会返回null。_Dart
里面没有undefined
的概念,目前看来所有对于js的undefined
都可以替换成null
_
1 2 foo() {} assert (foo() == null );
运算符 类型测试运算符 as
、is
、is!
类似 instanceof
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Person { var firstName= '2' ; } var a = new Person();var b;if (a is Person) { a.firstName = 'b' ; } if (b is ! Person) { print ('b is not person' ); } (a as Person).firstName = 'Bob' ;
分配运算符 1 2 a = value; b ??= value;
三目运算符 1 2 3 4 5 var vis = isPublic? 'public' : 'private' ;String playName(String name)=> name?? 'guest' ;
Cascade notation Cascade(..)
有点像链式写法的语法糖,允许您对同一对象进行一系列操作,不得不说这些语法糖真骚…
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 querySelect('#confirm' ) ..text = 'Confirm' ..classes.add('important' ) ..onClick.listen((e)=> window .alter('Confirmed!' )); var button = querySelector ('#confirm' );button.text = 'Confirm' ; button.classes.add('important' ); button.onClick.listen((e)=> window .alter('Confirmed!' )); final addressBook = (AddressBookBuilder() ..name = 'jenny' ..email = 'jsonz@qq.com' ..phone = ( PhoneNumberBuilder() ..number = '13560042631' ..label = 'phone' .build() ) .build(); )
其他操作符 ()
函数调用[]
list.
属性?.
一般用于属性赋值,比如 person?.name = 'jsonz'
(如果person不为null, 则设置person.name为jsonz,避免左边person为null时报错)。
控制流程语句 这里只会挑与js不同的来讲
if..else 不同点是Dart
不会隐式转换,所以判断的内容只能是布尔值
1 2 3 4 5 6 7 if (false ) {} else if (false ) { } else { }
loop for for in 1 2 3 4 var collection = ['a' , 'b' , 'c' ];for (var x in collection) { print (x); }
while && do-while break && continue break 停止循环 continue跳过当前次,进行下一次循环
Switch && case switch 可以对比 string
、number
、bool
但是不能混着用。
Assert(断言) 写过单元测试的应该对assert
不陌生,如果布尔条件为false
则assert
会中断执行。 不过只会在开发模式起作用,生产环境不会执行。
Other Throw 抛错 1 2 throw FormatException('expected at least 1 section' );throw 'out of llamas!' ;
catch 1 2 3 4 5 6 7 8 9 10 11 12 13 try { breedMoreLlamas(); } on OutOfLlamasException { buyMoreLlamas(); } on Exception catch (e) { print ('Unknown exception: $e ' ); } catch (e, s) { print ('Something really unknown: $e ' ); print ('Stack trace: \n $s ' ); }
finally 1 2 3 4 5 6 7 try { someThing() } catch (e) { print ('Error: $e ' ); } finally { clean(); }