微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Dart基础之常量构造函数和??=运算符

之前好像分享过一点儿Dart的基本知识,因为要使用Flutter开发,就必须学号Dart,所以,还是在这分享一下Dart的一些优雅的特性吧。

??= 运算符

在我们的Flutter的组件中,我们经常会使用三目运算符来判断一个对象的状态。其实这个也可以使用??=运算符来完成。

首先举个简单得例子:

// 测试??=运算符
// 为空则为赋值运算符后面的,不为空则为其本身

void main() {
  var isNull;
  var notNull = '我不为null';
  isNull ??= '为空吗?给你一个值';
  notNull ??= '为空吗?给你一个值';
  print(isNull);
  print(notNull);
}

然后我们再看一下Flutter中的具体应用:

1:我们首先创建一个loading.dart文件,然后在该文件中创建一个Loading.dart的StatelessWidget组件。

import 'package:Flutter/material.dart';

// 加载中的组件

class Loading extends StatelessWidget {

  const Loading({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
      child: Container( 
        margin: EdgeInsets.fromLTRB(20, 40, 20, 40),
        alignment: Alignment.center,
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          crossAxisAlignment: CrossAxisAlignment.center,
          children: <Widget>[
            Container(
              width: 50,
              height: 50,
              child: Image.asset('images/loading.png',
                  color: Colors.grey, fit: BoxFit.cover),
            ),
            SizedBox(height:20),
            Text(
              '加载中 ... ... ',
              style: TextStyle(color: Colors.black45),
              textAlign: TextAlign.center,
            )
          ],
        ),
      ),
    );
  }
}


没有什么,就是一个简单得页面

2:然后我们再创建一个简单得文本组件,就叫做hello_world.dart。在其中也是创建一个StatelessWidget组件,然后在里面创建一个Text组件即可。

import 'package:Flutter/material.dart';

// 需要显示页面组件

class HelloWorld extends StatelessWidget {
  const HelloWorld({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Center(
        child: Container(
            height: double.infinity,
            width: double.infinity,
            alignment: Alignment.center,
            color: Colors.yellow,
            child: Text(
              'Hello,Flutter!',
              style: TextStyle(color: Colors.white, fontSize: 44),
              textAlign: TextAlign.center,
            )));
  }
}


3:然后我们想实现这样一个效果,就是模拟一下数据请求,(我们在这儿使用延时调用来模拟),延时3000毫秒后再加载我们的页面

我们可以这样写:

import 'package:Flutter/cupertino.dart';
import 'package:Flutter/material.dart';
import 'package:learn_Flutter/pages/hello_world.dart';
import 'package:learn_Flutter/pages/loading.dart';

void main() => runApp(MainApp());

class MainApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MainAppState();
  }
}

class _MainAppState extends State<MainApp> {
  // 首先创建我们需要加载显示的Widget

  //此时,helloWorld为空
  HelloWorld helloWorld;

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration(milliseconds: 5000), () {
      setState(() {
        helloWorld = HelloWorld();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('测试??='),
        ),
       // 在这儿我们可以使用三目运算符来判断。
         body: helloWorld == null ? Loading() : helloWorld, 
      ),
    );
  }
}

当然,我们也可以使用我们的??=运算符来代替它。

但是如果要使用我们的??=运算符,那么,我们的两个Widget的类型必须相同。所以我们就得把HelloWorld这个组件声明为和Loading相同类型的组件,也就是我们的父组件Widget。

import 'package:Flutter/cupertino.dart';
import 'package:Flutter/material.dart';
import 'package:learn_Flutter/pages/hello_world.dart';
import 'package:learn_Flutter/pages/loading.dart';

void main() => runApp(MainApp());

class MainApp extends StatefulWidget {
  @override
  State<StatefulWidget> createState() {
    return _MainAppState();
  }
}

class _MainAppState extends State<MainApp> {
  // 首先创建我们需要加载显示的Widget

  //此时,helloWorld为空 注意定义为了Widget
  Widget helloWorld;

  @override
  void initState() {
    super.initState();
    Future.delayed(Duration(milliseconds: 5000), () {
      setState(() {
        helloWorld = HelloWorld();
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('测试??='),
        ),
        // 如果helloWorld为空的话,那么,加在Loading()组件,否则加载它本身。
        body: helloWorld ??= Loading(),
      ),
    );
  }
}

其实,这种写法我们大家了解即可,因为很多语言没有该运算符,但是却有三目运算符,所以,因人而异吧。你喜欢哪个就用哪个。

常量构造函数

当我们创建对象时,如果希望传入相同值,就返回同一个对象,这个时候,可以使用常量构造函数

来个例子:

我们就举个老师都会举得例子:

创建一个Person类:

class Person {
  String name;
  int id;

  Person(this.name,this.id);

  @override
  String toString() { 
    return 'name : ${this.name} , age : ${this.id}';
  }

}

然后就创建两个对象,然后我们希望如果该对象的姓名和id都相同的话,那么返回同一个对象。

直接这样做肯定会返回false

void main () {
  Person xiaoming1 = Person('小明',11111111); 
  Person xiaoming2 = Person('小明',11111111);
  print(xiaoming1 == xiaoming2);   // false
}

这个时候我们可能就需要写一个equals方法,来判断我们的属性值了,如果属性值相同的话就为一个对象,但是这样做好是好,但是有点麻烦。

这个时候来试一下常量构造函数

如果我们直接在构造函数前面加一个const关键字是不可以的,编辑器会给我们语法提示

无法为具有非final字段的类定义const构造函数
尝试将所有字段设置为final,或者从构造函数.da中删除关键字“const”

我们在这时会写出这样的代码

void main() {
  Person xiaoming1 =  Person('小明', 11111111);
  Person xiaoming2 =  Person('小明', 11111111);
  print(xiaoming1 == xiaoming2);  // false
}

class Person {
  final String name;
  final int id;
  const Person(this.name, this.id);
  @override
  String toString() {
    return 'name : ${this.name} , age : ${this.id}';
  }
}

这是,你会发现,我们的构造函数已经使用const关键字声明了,但是相同参数得到的对象也不是相同对象。

这是怎么回事?

因为常量构造函数不能使用new关键字来创建对象。

我们上面没用new关键字,系统会自动帮我们加上new关键字。

那你可能就好奇了,不用new我们用什么呢?

在这儿,使用常量构造函数时,需要使用const关键字来创建对象。

试着给上面的两个对象前面(赋值号右边)都加上const关键字。

void main() {
  Person xiaoming1 = const Person('小明', 11111111);
  Person xiaoming2 = const Person('小明', 11111111);
  print(xiaoming1 == xiaoming2);  // true
}

这时,我们的构造函数,就成为了常量构造函数

然后,再记住一点:

将创建的对象赋值给const修饰的标识符时,创建对象时的const可以省略.

也就意味着你可以这样写:

void main() {
  const Person xiaoming1 = Person('小明', 11111111);
  const Person xiaoming2 = Person('小明', 11111111);
  print(xiaoming1 == xiaoming2); // true
}

OK,总结一下我们的常量构造函数

  • 如果使用常量构造函数,那么这个类的所有字段必需都为final修饰的。
  • 在使用常量构造函数时,使用const关键字来创建对象或者使用const变量来接受该对象

不要忘了常量关键字的前提:参数相同。如果传入的参数不想同,那么,不管你使用什么声明,怎么接收对象,都不是同一个对象。


END

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐