Dart学习之基础语法(二 方法函数)

先说下我学习Dart函数的感受吧,我尝试用java语言的形式去学习Dart,但是令我意外的是,我刚迈出第一步Dart就把我踢出门外。什么意思呢?比如说,在Java中我们可以重载函数,但是Dart它没有,再比如说返回值类型,在Java中我们必须特定的给出,不然Java编译器它不认识,但是Dart不一样,Dart我们可以不指定返回值类型。总之,就是感觉学起来特别的有意思,可能是因为Dart在不断的给我惊喜吧,让我有了想不断去探索的决心。

                                                    

一、普通函数

1.指定返回值得函数

 
  1. /**

  2. * 无返回值的函数

  3. * params: 可以是任意类型(var和Object类型也可以任意类型)。 当然这里的参数类型你可以随意指定我这里已dynamic为例

  4. * 参数类型:你也可以指定var、Object等,再比如说你可以指定num, int,double, String....

  5. * 如果我们对参数没有限制的话可以使用这个

  6. */

  7. void printDynamicParams(dynamic params){

  8. print(params);

  9. }

主函数中我们调用printDynamicParams函数:

 
  1. main(List<String> arguments) {

  2. printDynamicParams(12.33);

  3. printDynamicParams('liyahong');

  4. printDynamicParams("Dart Method test");

  5. printDynamicParams(10);

  6. printDynamicParams(true);

  7. }

控制台输出结果:

这里我们可以传入任意类型,适用于参数类型不固定的情况使用。这里大家可能会有一个疑惑,包括我当时学习的时候也有这个疑惑,既然dynamic、var、Object都可以指定任意类型,那它们有什么区别吗?下面我们就来说下这个问题。

(1)var

var是C# 3中引入的,其实它仅仅只是一个语法. var本身并不是一种类型, 其它两者object和dynamic是类型。var声明的变量在赋值的那一刻,就已经决定了它是什么类型。

如果你这样使用,就会有编译错误:

 
  1. var a = 1;

  2. a = "Test";

(2)Object

object之所以能够被赋值为任意类型的原因,其实都知道,因为所有的类型都派生自object. 

它可以赋值为任何类型:

 
  1. object a = 1;

  2. a = "Test";

(3)dynamic

dynamic不是在编译时候确定实际类型的, 而是在运行时。

所以下面的代码是能够通过编译的,但是会在运行时报错:

 
  1. dynamic a = "test";

  2. a++;

2.不指定返回值类型的函数

 
  1. /**

  2. * 我们可以不指定返回值类型,这样的函数返回值默认为Object,也就是说你可以返回任意类型

  3. * params: 可以是任意类型

  4. */

  5. printReturnObjectParams(Object params){

  6. print(params);

  7. return params;

  8. }

  9. printObjectParams(Object params){

  10. print(params);

  11. }

主函数中我们调用printReturnObjectParams 和 printObjectParams函数:

 
  1. main(List<String> arguments) {

  2. print(printReturnObjectParams("liyahong"));

  3. print(printReturnObjectParams(111));

  4. print(printReturnObjectParams(12.36));

  5.  
  6. print(printObjectParams(true));

  7. printObjectParams('test');

  8. }

控制台输出结果:

由上面的结果可以看出,如果没有返回值得时候默认将会返回null。

3.如果你的函数中只有一个表达式,你可以使用快速写法

 
  1. /**

  2. * 无返回值类型函数的快速写法

  3. * 注意:这种写法只适用于无返回值 并且 函数体中仅有一个表达式的函数。

  4. */

  5. void printNumber(num number) => print(number);

主函数中我们调用printNumber函数:

 
  1. printNumber(123);

  2. printNumber(22.3333);

控制台输出结果:

这里我们提到了num关键字,在上篇博客中没有讲到,这里简单说一下。

我们先看一下官方对它的说法:

 
  1. /**

  2. * An integer or floating-point number.

  3. * It is a compile-time error for any type other than [int] or [double]

  4. * to attempt to extend or implement num.

  5. */

  6.  
  7. 翻译:

  8. /**

  9.   * 整数或浮点数。

  10.   * 除[int]或[double]之外的任何类型都是编译时错误

  11.   * 试图扩展或实现num。

  12.   */

也就是说它是一个数值类型,仅支持int 和 double类型。

4.可选参数

一个函数可以有两种参数:可选的和必需的,必需参数放在前面,后面跟可选参数 

可选参数可以是位置参数或命名参数,两种都可以有默认值,如果没有提供默认值则为null

(1)可选的命名参数

定义一个函数,使用 {param1, param2, …} 指定命名参数,调用函数时,你可以指定使用命名参数 paramName: value

无默认值例子:

 
  1. /**

  2. * 没有默认值

  3. */

  4. void printBool({bool flag, bool action}) => print("flag: " + flag.toString() + "\r\naction: " + action.toString() + "\r\n");

有默认值(命名参数使用“:”指定默认值)例子:

 
  1. /**

  2. * 有默认值

  3. */

  4. void printDefaultBool({bool flag: false}) => print(flag);

主函数中我们调用printBool 和 printDefaultBool函数:

 
  1. main(List<String> arguments) {

  2. printBool(flag: true, action: false);

  3. printBool(flag: false);

  4. printBool();

  5.  
  6. printDefaultBool(flag: true);

  7. printDefaultBool();

  8. }

控制台输出结果:

(2)可选的位置参数

把参数用 [ ] 包装起来,就能标识成位置参数

无默认值例子:

 
  1. /**

  2. * 可选的位置参数

  3. * 无默认值

  4. */

  5. String msg(String msg, [String time]){

  6. if (time != null) {

  7. return msg + ' with ' + time;

  8. }

  9.  
  10. return msg;

  11. }

有默认值(位置参数使用“=”指定默认值)例子:

 
  1. /**

  2. * 可选的位置参数

  3. * 有默认值

  4. */

  5. String msgTwo(String msg, [String time = '2018', String name]){

  6. if (time == null) {

  7. return msg + " from " + name;

  8. }

  9.  
  10. if (name != null) {

  11. return msg + " with " + time + " from " + name;

  12. }

  13.  
  14. return msg + " with " + time;

  15. }

主函数中我们调用msg 和 msgTwo函数:

 
  1. print(msg("This is msg content", '2017'));

  2. print(msg("Tiis is msg content"));

  3.  
  4. print(msgTwo("This is msgTwo content", '2017', 'liyahong'));

  5. print(msgTwo("This is msgTwo content", null, 'liyahong'));

  6. print(msgTwo("This is msgTwo content"));

控制台输出结果:

总结:可选的命名参数的声明使用“{}”,使用“:”指定默认值,可选的位置函数的声明使用“[]”,使用“=”指定默认值。

6.关于重载

Dart语言是不支持方法重载的。这里可能会有人问:“Dart不支持方法重载,那构造函数怎么办呢?”,虽然Dart它不支持方法的重载,但是它支持命名构造函数,我们通过下面例子学习一下:

 
  1. class Test{

  2. int x;

  3. int y;

  4.  
  5. Test(){}

  6.  
  7. Test.X(int x){

  8. this.x = x;

  9. }

  10.  
  11. Test.Y(int y){

  12. this.y = y;

  13. }

  14.  
  15. Test.XY(int x, int y){

  16. this.x = x;

  17. this.y = y;

  18. }

  19.  
  20. @override

  21. String toString() {

  22. if (x != null && y != null) {

  23. return "x: " + x.toString() + " y: " + y.toString();

  24. }

  25.  
  26. if (x != null) {

  27. return "x: " + x.toString();

  28. }

  29.  
  30. if (y != null) {

  31. return "y: " + y.toString();

  32. }

  33.  
  34. return super.toString();

  35. }

  36. }

我们在主函数中创建Test对象:

 
  1. main(List<String> arguments) {

  2. Test testX = new Test.X(1);

  3. print(testX.toString());

  4.  
  5. Test testY = new Test.Y(2);

  6. print(testY.toString());

  7.  
  8. Test testXY = new Test.XY(3, 4);

  9. print(testXY.toString());

  10. }

控制台输出结果:

具体内容我们后面讲解。

                                                                 

7.高级函数

 
  1. /**

  2. * 高级函数

  3. * element 没有指定参数类型,默认Object任何类型

  4. */

  5. printElement(element){

  6. print(element);

  7. }

在主函数中调用printElement函数,这里是将函数作为参数传入

 
  1. main(List<String> arguments) {

  2. var list = ['张三', '李四', '王麻子'];

  3. list.forEach(printElement);

  4. }

控制台输出结果:

将一个函数分配给一个变量

 
  1. main(List<String> arguments) {

  2. var loudify = (msg) => '${msg.toUpperCase()}';

  3. print(loudify('hello'));

  4. }

控制台输出结果:

8.作用域

dart的作用域跟其他语言一样,直接看一个例子

 
  1. var test = true;

  2.  
  3. main(List<String> arguments) {

  4. var test1 = true;

  5.  
  6. myFunction(){

  7. var test2 = true;

  8.  
  9. needFunction(){

  10. var test3 = true;

  11.  
  12. assert(test);

  13. assert(test1);

  14. assert(test2);

  15. assert(test3);

  16. }

  17. }

  18. }

9.闭包

dart的闭包就是函数对象,其实跟JavaScript的闭包函数差不多,理论请参考JavaScript的闭包函数,这里直接写个例子

 
  1. //返回一个函数对象,功能是返回累加的数字

  2. Function makeAdder(num addBy) {

  3. return (num i) => addBy + i;

  4. }

  5.  
  6. main(List<String> arguments) {

  7. //创建一个函数add2,add2返回2

  8. var add2 = makeAdder(2);

  9.  
  10. //创建一个函数add4,add4返回4

  11. var add4 = makeAdder(4);

  12.  
  13. //add2返回2+3

  14. assert(add2(3) == 5);

  15. //add4返回4+3

  16. assert(add4(3) == 7);

  17. }

10.函数是否相等

测试高阶函数、静态方法和实例方法是否相等

 
  1. //一个高阶函数

  2. foo() {}

  3.  
  4. class SomeClass {

  5. //一个静态方法

  6. static void bar() {}

  7. //一个实例方法

  8. void baz() {}

  9. }

  10.  
  11. main(List<String> arguments) {

  12. var x;

  13.  
  14. //比较高阶函数

  15. x = foo;

  16. assert(foo == x);

  17.  
  18. //比较静态方法

  19. x = SomeClass.bar;

  20. assert(SomeClass.bar == x);

  21.  
  22. //比较实例方法

  23. var v = new SomeClass();

  24. var w = new SomeClass();

  25. var y = w;

  26. x = w.baz;

  27.  
  28. assert(y.baz == x);

  29. assert(v.baz != w.baz);

  30. }

参考:Dart基础-函数:https://blog.csdn.net/hekaiyou/article/details/46639683

          var,Object,dynamic的区别:https://blog.csdn.net/mrobama/article/details/53812898

发布了96 篇原创文章 · 获赞 370 · 访问量 42万+

猜你喜欢

转载自blog.csdn.net/wk_beicai/article/details/90479026