[Flutter]足够入门的Dart语言系列之常见运算符或操作符

简介: Dart中的运算符提供对数据操作和处理的能力,其中的算术运算符、逻辑运算符非常符合现实中的使用情况,其他不同的运算符则有着自己的操作逻辑...
Operator运算符,通常也称为“操作符”。

Dart中的运算符提供对数据操作和处理的能力,其中的算术运算符、逻辑运算符非常符合现实中的使用情况,其他不同的运算符则有着自己的操作逻辑。

下面是Dart中运算符描述【可先做了解】,其前后顺序表示了优先级(即多个操作符使用时,优先计算的顺序,使用()可以改变优先级)

描述 运算符
一元后缀 表达式++ 表达式-- () [] . ?. !
一元前缀 -表达式 !表达式 ~表达式 ++表达式 --表达式
乘除法 * / % ~/
加减法 + -
位运算 << >> >>>
二进制与 &
二进制异或 ^
二进制或 ` `
关系和类型测试 >= > <= < as is is!
相等判断 == !=
逻辑与 &&
逻辑或 ` `
空判断 ??
条件表达式 _表达式 1_ ? _表达式 2_ : _表达式 3_
级联 .. ?..
赋值 = *= /= += -= &= ^= 等等……

算术运算符(Arithmetic operators

算术运算

算术运算是最基础的数值计算,包括:

  • + Add
  • - Subtract
  • -expr 减去,也称为负 (表达式的符号反转)
  • * Multiply
  • / Divide 返回double类型的相除的结果。
  • ~/ 返回相除的整数,即取商,大多数编程语言/会返回结果的整数。
  • % 取余(或取模),返回两个数相除的余数。

如下,算术运算符的使用:

int a = 10;
int b = 3;
print(a + b); // 13
print(a - b); // 7
print(a * b); // 30
print(a / b); // 3.3333333333333335
print(a ~/ b); // 3
print(a % b); // 1

精度问题

对于浮点数来说,会有精度损失的问题,通常按需要能满足精度要求即可(比如小数后几位)。

double a = 10.6;
double b = 3.3;
print(a + b); // 13.899999999999999
print(a - b); // 7.3
print(a * b); // 34.98
print(a / b); // 3.2121212121212124
print(a ~/ b); //3
print(a % b); // 0.7000000000000002

身高、体重、长度等一般保留两三位小数即可。对于金融场景下,需要非常高精度计算的时候,推荐使用decimal第三方库。

条件运算符(比较运算符,或Equality and relational operators

比较运算符用于比较变量,其结果返回一个bool值。

  • == 相等
  • `!= 不等
  • > 大于
  • < 小于
  • >= 大于等于
  • <= 小于等于

如下,变量a、b比较运算:

int a = 5;
int b = 6;
print(a > b); // false
print(a < b); // true
print(a == b); // false
print(a != b); // true
print(a >= b); // false
print(a <= b); // true

逻辑运算符(Logical operators

逻辑运算是对bool(真、假)的运算。有与-&&或-||非-!三种。

  • && —— 与运算,当两边都为true时,结果才为true。表示的是并且/同时
  • || —— 或运算,当两边有一个为true时,结果就为true。表示的是或者/满足其中一个
  • ! —— 非或取反运算,对表达式的bool值取反。表示的是不是/

比如,对于游乐场的要求:

身高小于1.4,并且年龄小于16才能游玩,则可以如下表示:

int age = 16;
double height = 1.3;
if(age<16 && height<1.4){
    print("允许游玩");
}
else{
  print("不允许游玩");
}

// 不允许游玩

身高小于1.4,或年龄小于16才能游玩,则可以如下表示:

int age = 16;
double height = 1.3;
if(age<16 || height<1.4){
    print("允许游玩");
}
else{
  print("不允许游玩");
}

// 允许游玩

身高大于1.4或年龄大于16,不满足这个条件的就能游玩,则可以如下表示:

int age = 16;
double height = 1.3;
if (!(age > 16 || height > 1.4)) {
  print("允许游玩");
} else {
  print("不允许游玩");
}

// 允许游玩
逻辑运算符的“短路”特点:

&&||两元逻辑运算符在计算时,如果左侧的表达式就能确定逻辑结果时,则不会对右侧的表达式进行取值计算。

&&左侧为false,结果必然为false(一假全假);||左侧为true,结果必然为true(一真全真)。由于短路策略,则不会进行右侧表达式多余的计算。

位运算符(Bitwise and shift operators

位运算针对的是计算机中的二进制位进行的运算,它是计算机中一切数据运算的本质(逻辑运算、算术运算、比较运算等都要转换为位运算)。

位运算符包括:

  • & 按位与
  • | 按位或
  • ^ 按位异或
  • ~expr 按位取反(即将 “0” 变为 “1”,“1” 变为 “0”)
  • << 位左移
  • >> 位右移
  • >>> 无符号右移
final value = 0x22;
final bitmask = 0x0f;

assert((value & bitmask) == 0x02); // AND
assert((value & ~bitmask) == 0x20); // AND NOT
assert((value | bitmask) == 0x2f); // OR
assert((value ^ bitmask) == 0x2d); // XOR
assert((value << 4) == 0x220); // Shift left
assert((value >> 4) == 0x02); // Shift right
assert((value >>> 4) == 0x02); // Unsigned shift right
assert((-value >> 4) == -0x03); // Shift right
assert((-value >>> 4) > 0); // Unsigned shift right

体会下按位计算的特点:

int类型在内存中占据 4 字节,每字节(byte)由 8 个二进制位(bit)表示。

65 、11 在计算机中以 32 个二进制位来记录:

十进制: 65
二进制: 0000 0000 0000 0000 0000 0000 0100 0001

十进制: 11
二进制: 0000 0000 0000 0000 0000 0000 0000 1011
  • &按位与
int a = 65;
int b = 11;
int c = a & b;

  0000 0000 0000 0000 0000 0000 0100 0001     a = 65
& 0000 0000 0000 0000 0000 0000 0000 1011     b = 11
  0000 0000 0000 0000 0000 0000 0000 0001     c = 1
  • |按位或
int a = 65;
int b = 11;
int c = a | b;

  0000 0000 0000 0000 0000 0000 0100 0001     a = 65
| 0000 0000 0000 0000 0000 0000 0000 1011     b = 11
  0000 0000 0000 0000 0000 0000 0100 1011     c = 75
  • ~按位取反
int b = 11;
int c = ~b;
  0000 0000 0000 0000 0000 0000 0000 1011  b = 11
~ 1111 1111 1111 1111 1111 1111 1111 0100  c = -12

print(c);   // -12
print(~c);  // 11

1111 1111 1111 1111 1111 1111 1111 0100作为机器码,最高位表示符号位,计算机将数据存储为补码的形式,也就是,-12的补码为1111 1111 1111 1111 1111 1111 1111 0100

如果是无符号整数,则其取值将为4294967284

原码是符号位和真值的绝对值,比如 -12 的原码表示:最高位为符号位,后面为其真值的绝对值。

-12 原码:  1000 0000 0000 0000 0000 0000 0000 1100

正数的反码是其本身;负数的反码是在其原码的基础上, 符号位不变,其余各个位取反:

-12 原码:  1000 0000 0000 0000 0000 0000 0000 1100
-12 反码:  1111 1111 1111 1111 1111 1111 1111 0011

正数的补码也是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即反码+1)

-12 原码:  1000 0000 0000 0000 0000 0000 0000 1100
-12 反码:  1111 1111 1111 1111 1111 1111 1111 0011
-12 补码:  1111 1111 1111 1111 1111 1111 1111 0100

这就是上面取值为-12的原因。

  • ^按位异或
int a = 65;
int b = 11;
int c = a ^ b;

  0000 0000 0000 0000 0000 0000 0100 0001     a = 65
^ 0000 0000 0000 0000 0000 0000 0000 1011     b = 11
  0000 0000 0000 0000 0000 0000 0100 1010     c = 74
  • <<>>按位进行左移和右移
int a = 65;
int c = a << 2;

0000 0000 0000 0000 0000 0000 0100 0001     a = 65
0000 0000 0000 0000 0000 0001 0000 0100        c = 260

赋值运算符(Assignment operators

赋值运算符用于将一个值赋值给变量。使用的是=等于号,左侧为变量,右侧为可以获取的值(字面量、变量、表达式、函数等)。

  • =用于直接赋值。
  • ??=用于为值为null的变量赋值。
int a = 10;
int b = a + 40;

??=当变量为null时,才会进行赋值,是对null判断并赋值的一种语法糖(简写形式)。

int? a;


a??=10;

// 等价于
if(a==null){
    a=10;
}

=??=的同时使用:

int b = a ??= 20;
  • 组合赋值运算符

算数运算符、位运算符可以和赋值运算符进行组合,本质是两种运算符的简写。

比如 +=

int a = 10;
a += 20;

// 等同 a = a + 20;

此外还有:+= -= *= /= %= ~/= &= |= ^= <<= >>= >>>=

目前没有 ~=

--++自增自减运算符

自增自减运算符分为前置和后置两种类型。前置自增/自减是先进行自增/自减运算然后再取值;后置自增/自减是先取值然后再进行自增/自减。

var a = 10;
var b = 15;

var c = a++;
var d = b--;

var e = ++a;
var f = --b;

print('a=$a');
print('b=$b');
print('c=$c');
print('d=$d');
print('e=$e');
print('f=$f');

输出结果如下,可以对比了解前置自增/自减、后置自增/自减的区别:

a=12
b=13
c=10
d=15
e=12
f=13

条件表达式(Conditional expressions

条件表达式可以用来替代if-else语句,使条件处理更加简明。

condition?expr1:expr2 如果条件为真,执行 表达式1 并返回结果,否则执行 表达式2 并返回结果。

expr1 ?? expr2 如果 表达式1 不为 null 则返回其值,否则执行 表达式2 并返回其值。

如下,根据布尔表达式确定取值:

var visibility = isPublic ? 'public' : 'private';

根据是否为null确定取值:

var result = name ?? 'Guest';

??可以用?:三元表达式来实现:

var result = name!=null?name:'Guest';
?:有三个表达式,因此也被称为三元运算符,或三目运算符。

上面介绍的其他运算符,比如+-*/等有两个表达式,被称为二元或二目运算符;!~++等有一个表达式,被称为一元或单目运算符。

类型判断运算符(Type test operators)

as、is、is! 运算符用于在运行时判断对象的类型。

  • as 类型转换
  • is 如果对象是指定类型则返回 true
  • is! 如果对象是指定类型则返回 false

后续在对象的使用中进一步了解。

参考

相关文章
|
2月前
|
前端开发 C++ 容器
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)
Flutter-完整开发实战详解(一、Dart-语言和-Flutter-基础)(1)
|
2月前
|
Dart 前端开发 开发工具
【Flutter前端技术开发专栏】Flutter入门指南:搭建开发环境与第一个应用
【4月更文挑战第30天】本文介绍了Flutter SDK的安装和配置过程,以及如何创建并运行第一个Flutter应用。首先确保安装了Dart SDK和Flutter SDK,支持macOS、Linux和Windows。安装完成后,设置环境变量,然后通过`flutter doctor`验证安装。接着,使用`flutter create`命令创建新项目,进入项目目录并运行`flutter run`启动应用。在`main.dart`中修改代码以自定义应用。Flutter支持热重载和DevTools调试。本文为Flutter初学者提供了快速入门的指导。
【Flutter前端技术开发专栏】Flutter入门指南:搭建开发环境与第一个应用
|
2月前
|
Dart 安全
简化代码、提高效率:Dart和Flutter开发小技巧
在日常开发中,我们常常会使用一些常用的技巧或语法糖,以简化代码、提高开发效率。本文将分享一些在Dart和Flutter中常用的小贴士,帮助你更轻松地编写优雅高效的代码。
简化代码、提高效率:Dart和Flutter开发小技巧
|
11天前
|
Dart
flutter 之 Dart 异步编程【详解】
flutter 之 Dart 异步编程【详解】
6 0
|
26天前
|
移动开发 小程序 安全
基础入门-APP架构&小程序&H5+Vue语言&Web封装&原生开发&Flutter
基础入门-APP架构&小程序&H5+Vue语言&Web封装&原生开发&Flutter
|
2月前
|
数据库 Android开发
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
Android数据库框架-GreenDao入门,2024年最新flutter 页面跳转动画
|
2月前
|
Dart 前端开发 开发者
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
【4月更文挑战第30天】Dart是Google为Flutter框架打造的高效编程语言,具有易学性、接口、混入、抽象类等特性。本文概述了Dart的基础语法,包括静态类型(如int、String)、控制流程(条件、循环)、函数、面向对象(类与对象)和异常处理。此外,还介绍了库导入与模块使用,帮助开发者快速入门Flutter开发。通过学习Dart,开发者能创建高性能的应用。
【Flutter前端技术开发专栏】Flutter Dart语言基础语法解析
|
开发工具 Android开发 iOS开发
Flutter从入门到实战
版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/u013132758。 https://blog.csdn.net/u013132758/article/details/80474494 Flutter从入门到实战 Flutter概述   Flutter是一款移动应用程序SDK,一份代码可以同时生成iOS和Android两个高性能、高保真的应用程序。
2237 0
|
2月前
|
缓存 监控 前端开发
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
【4月更文挑战第30天】本文探讨了Flutter应用启动优化策略,包括理解启动过程、资源加载优化、减少初始化工作、界面布局简化、异步初始化、预加载关键数据、性能监控分析以及案例和未来优化方向。通过这些方法,可以缩短启动时间,提升用户体验。使用Flutter DevTools等工具可助于识别和解决性能瓶颈,实现持续优化。
【Flutter 前端技术开发专栏】Flutter 应用的启动优化策略
|
27天前
|
开发框架 前端开发 测试技术
Flutter开发常见问题解答
Flutter开发常见问题解答