字符串插值
为了将表达式的值放在字符串中,请使用${expression} 如果表达式为单个值就可以省略{}
列:
'${3+2}' '5'
'${"dart".toUpperCase}' 'DART'
'$hiDart.toString()' 'hiDart'
避空运算符
Dart提供了一系列方便的运算符来处理可能会为空得变量.其中一个是??=
赋值运算符 当改变量为空时为其赋值;
int d;
d ??= 100;
print(d); //---------->100
d ?== 333;
print(d); //---------->100
??
避空运算符,如果运算符左边表达式返回的是空值,则会计算右边表达式并且返回值
print(1??3); //------------>1
print(null??11); //--------------->11
条件属性访问
要保证可能为空的属性正常访问,可以在.
的前面添加一个问号?
object?.someProperty;
//相当于
object!=null:object.somProperty:null
在一个表达式中可以连续使用多个 ?.
//当a 或者 a?.b 为空时,前面代码返回null并且不会调用c()
a?.b?.c();
集合字面量(Collection literals)
Dart内置了对list,map以及set的支持,你可以通过字面量直接创建他们:
final aListOfStrings = ['one','two','three'];
final aSetOfStrings ={'one','two','three'};
final aMapOfStringsToInts{
'one':'1',
'two':'2',
'three':'3'
}
Dart的类型推断可以自动帮你分配这些变量的类型,这个例子中推断类型是List<String> , Set<String> 和Map<String,int>.
也可以手动写出
final aListOfInts = <int>[];
final aSetOfInts = <int>{};
final aMapOfIntToDouble = <int,double>{};
在使用子类型的内容初始化列表,但仍希望列表为List<BaseType> 时,指定齐类型很方便:
final aListOfBaseType = <BaseType>[SubType(),SubType()];
箭头语法
=>
这种箭头语法是一种定义函数的方法,该函数将在其右侧执行表达式并返回其值.
bool hasEmpty = aListOfStrings.any((any){
return s.isEmpty;
});
bool hasEmpty = aListOfStrings.any((s) => s.isEmpty);
级连
要对同一对象执行一系列操作,请使用 ..
//在myObject上调用someMethod()方法,返回的结果是someMethod的值
myObject.someMethod();
//在myObject上调用someMethod()方法,但是结果返回不是该方法的返回值,而是myObject对象的引用
myObject..someMethod();
//使用级练 你可以将需要单独操作的语句链接到一起
var button = querySelector('#confirm');
button.text = 'Confirm';
button.classes.add('important');
button.onClick.listen((e)=> window.alert('Confirmed!'));
//使用级连能让代码更加简洁,而且在也不需要button变量了
querySelector('#confirm')..text = 'Confirm'..classes.add('important')..onClick.listen((e) => window.alert('Confirmed!'));
Getters and Setters
任何需要对属性进行更多控制而不是允许简单字段访问的时候,你都可以自定义getter 和 setter
你可以用来确保属性值合法:
class MyClass{
int _aProperty = 0;
int get aProperty => _aProperty;
set aProperty(int value){
if(value>=0){
_aProperty =value;
}
}
}
//可以使用get来进行计算
class MyClass{
List<int> _value = [];
void addValue(int value){
_value.add(value);
}
int get count{
return _value.length;
}
}
可选位置参数
Drat 有两种传参方法:位置参数和命名参数.
int sunUp(int a,int b,int c){
return a+b+c;
}
int total = sunUp(1,2,3);
在dart中,你可以通过将这些参数包囊在大括号中使其变成可选位置参数:
int sumUpToFive(int a,[int b,int c,int d,int e]){
int sum = a;
if(b!=null) sum+=b;
if(c!=null) sum+=c;
if(d!=null) sum+=d;
if(e!=null) sum+=e;
return sum;
}
int total = sumUpToFive(1,2);
int otherTotal = sumUpToFive(1,2,3,4,5);
可选参数永远放在参数列表最后.除非你给他提供一个默认的值,否则默认为null
可选命名参数
你可以使用大括号语法定义可选命名参数;
void printName(String firstName,String lastName,{String suffix}){
print('$firstName $lastName ${suffix ?? ''}');
}
printName('Avinash', 'Gupta');
printName('Poshmeister', 'Moneybuckets', suffix: 'IV');
这些参数默认值为null,但是你可以为其提供默认值
void printName(String firstName, String lastName, {String suffix = ''}) {
print('$firstName $lastName ${suffix}');
}
异常
Dart 代码可以抛出和捕获异常,与java相比,Dart所有的异常都是unchecked execption.方法不会声明他们可能抛出的异常,你也不需要捕获任何异常
虽然dart提供了exception 和 error 类,但你可以抛出任何非空对象
throw Exception('Something bad happened');
throw 'xxxxxxxxxxx';
使用try
、on
catch
关键字来处理异常
try{
breedMoreLlamas();
} on OutOfLlamasException{
buyMoreLlamas();
} on Exception catch(e){
print('Unknown exception:$e');
} catch(e){
print('Something really unknown: $e');
}
try
关键字和其他大多数语言作用一样. 使用on
关键字按类型过滤特定异常,而catch关键字则能捕捉到异常对象的引用;
如果你无法完全处理异常,请使用rethrow
关键字再次抛出异常
try{
breedMoreLlamas();
}catch(e){
print('I was just trying to breed llamas');
rethrow;
}
要执行一段无论是否抛出异常都会执行的代码,请使用finally
;
try {
breedMoreLlamas();
} catch (e) {
… handle exception ...
} finally {
// Always clean up, even if an exception is thrown.
cleanLlamaStalls();
}
在构造方法中使用this
Dart 提供了一个方便的快捷方式,用于为构造方法中的属性赋值:在声明构造方法时使用this.propertyName
class MyColor{
int red;
int green;
int blue;
MyColor(this.red,this.green,this.blue)
}
final color = MyColor(33,33,33);
此技巧同样也适用于命名参数。属性名为参数的名称:
class MyColor {
...
MyColor({this.red, this.green, this.blue});
}
final color = MyColor(red: 80, green: 80, blue: 80);
对于可选参数,默认值为期望值:
MyColor([this.red = 0, this.green = 0, this.blue = 0]);
// or
MyColor({this.red = 0, this.green = 0, this.blue = 0});
Initializer lists
有时,当你在实现构造函数时,您需要在构造函数体执行之前进行一些初始化。例如,final 修饰的字段必须在构造函数体执行之前赋值。在初始化列表中执行此操作,该列表位于构造函数的签名与其函数体之间:
Point.fromJson(Map<String, num> json)
: x = json['x'],
y = json['y'] {
print('In Point.fromJson():
初始化列表也是放置断言的便利位置,它仅会在开发期间运行:
NonNegativePoint(this.x, this.y)
: assert(x >= 0),
assert(y >= 0) {
print('I just made a NonNegativePoint: ($x, $y)');
}
命名构造方法
为了允许一个类具有多个构造方法,Dart支持命名构造方法;
class Point{
num x,y;
Point(this.x,this.y);
Point.origin(){
x=0;
y=0;
}
}
为了使用命名构造方法,请使用全命名调用它;
final myPoint = Point.origin();
工厂构造方法
Dart 支持工厂构造方法, 它能够返回其子类甚至null对象.要创建一个工厂构造方法,请使用factory关键字.
class Square extends Shape{}
class Circle extends Shape{}
class Shape{
Shape();
factory Shape.formTypeName(String typeNmae){
if(typeName == 'square') return Square();
if(typeName == 'circle') return Circle();
print('I don\'t recognize $typeName');
return null;
}
}
重定向构造方法
有时候一个构造方法仅仅用来重定向到该类的另外一个构造方法,重定向方法没有主体.它在冒号:
之后调用另外一个构造方法
class Automobile{
String make;
String model;
int mpg;
Automobile(this.make,this.model,this.mpg);
Automobile.hybrid(String make,String model):this(make,model,60);
Automobile.fancyHybrid():this.hybrid('Futurecar','Mark 2');
}
Const构造方法
如果你的类生成对象永远都不会改变,则可以让这些对象成为编译时常量.为此定义const
构造方法并且确保所有实例变量都是final;
class ImmutablePoint{
const ImmutablePoint(this.x,this.y);
final int x;
final int y;
static const ImmutablePoint origin = ImmutablePoint(0,0);
}