C#TS和Dart对比3:编译时常量和运行时常量
Posted functionMC
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#TS和Dart对比3:编译时常量和运行时常量相关的知识,希望对你有一定的参考价值。
一、理清一下数据的命名习惯
本地变量、本地常量、成员变量、成员常量、实例变量、静态变量、字段、属性......不同开发语言,对定义在方法和类中的数据有不同的命名方式。在学习常量之前,先理清一下。以下仅是我的习惯,大家可以参考一下:
1、在方法中:①变量称为本地变量,常量称为本地常量;②TS和Dart都存在全局作用域,如果是在全局作用域中定义的变量和常量,则分别称之为全局变量和全局常量;③参数是比较特殊的变量,方法定义时称之为形参,方法调用时称之为实参。
2、在类中:①将字段称为数据成员,属性、函数等称为方法成员;②字段根据不同作用和性质,划为实例变量字段、实例常量字段、静态变量字段、静态常量字段,属于类的数据成员;②拥有对应的getter和setter方法的字段,将字段、getter和setter打包在一起,统称为属性,和函数一样,属于类的方法成员。
二、常量的一些概念
1、变量初始化或赋值后,值还可以改变,但常量一旦初始化或赋值后,值不可变。
2、有一些常量,必须在定义常量的时候初始化赋值,值在编译期决定,称之为编译时常量。C#、TS和Dart中,都使用const来定义,但使用略有区别,详见下文。
3、而有一些常量,即可以在编译期初始化赋值,也可以先定义,然后在运行时再赋值,称之为运行时常量。C#和TS中,使用readonly关键词来定义,且只能在类中使用;而Dart使用final关键词来定义,即可以在类中使用,也可以在方法中使用。
4、补充:Dart是为flutter而生的,而flutter中,const和final使用非常广泛,所以需要特别掌握。
三、编译时常量
1、C#中的const:即可以在方法中使用,也可以在类中使用。在类中使用时,具有静态字段特征(但不需要用static关键词修饰),可以通过【类名.常量名】的方式访问。
public class Program public const int age = 18; //定义类中的实例常量字段,是类的数据成员。具有static静态成员的特征。 static void Main(string[] args) //const int a; //报错,const定义编译时常量,必须初始化赋值 const int a = 1; //定义方法中的本地常量 //a = 2; //报错,常量赋值后不能再改变 Console.WriteLine(age); //在方法中使用类的常量字段 Console.WriteLine(a); //1
2、TS中的const:只能在方法中使用,不能在类中使用
class Program //public const a2:number = 1; //报错,不能在类中使用const创建数据成员 main():number const a2:number = 2; //定义本地常量 return a1+a2; //const a1:number; //报错,const定义常量(此处为全局常量),必须初始化赋值 const a1:number = 1; //定义全局常量 let p1 = new Program(); console.log(a1); //1 console.log(p1.main()); //3
3、Dart中的const:即可以在方法中使用,也可以在类中使用。在类中使用时,不能使用const创建实例常量字段,必须定义为静态常量字段【static const...】。
void main() //const int a; a = 1; //报错,const创建常量时,必须初始化赋值 const int a1 = 1; const a2 = 2; //使用const定义常量,具有类型推荐功能,可以省略类型声明 const a3 = 2*a2; //可以使用其它常量为const常量赋值 /* * 以下为难点,const不仅可以定义常量,还可以用于创建常量值 * 使用const创建常量值,主要用于创建常量构造函数。常量构造函数创建的对象,不可以改变 */ var a4 = const []; //const创建了一个空数组常量值,并赋值给变量a4 a4 = [1]; //变量a4仍然可以改变,不能变的是使用【const []】创建的常量值 const a5 = const []; //表达式一定是常量的上下文中,可以消除冗余,等效于const a5 = []; //a5 = [1]; //报错,a5是常量,不能更改 print(a1); //1 print(a2); //2 print(a3); //4 print(a4); //[1] print(Employee.age); //18。直接通过类调用静态常量字段 class Employee //const age = 18; //报错,const只可以创建静态常量字段 static const age = 18;
四、运行时常量
1、C#中的readonly:在类中定义静态常量字段和实例常量字段,在运行时设置值
public class Program public const int age = 18; //定义类中的常量字段,是类的数据成员 static void Main(string[] args) var s1 = new Shape(1.0,2.0); //s1.NumberOfSides = 5; //报错,实例常量无法修改 public class Shape public static readonly string Color = "red"; //readonly常量可以定义为静态字段,声明时可以初始化 public readonly int NumberOfSides; //readonly常量也可以定义为实例字段,且可以是运行时常量,声明时不初始化 //readonly常量NumberOfSides的值,在运行时决定,可以根据不同的构造函数设置不同的值 public Shape(double side1,double side2) this.NumberOfSides = 4; Console.WriteLine("构造一个矩形"); public Shape(double side1,double side2,double side3) this.NumberOfSides = 3; Console.WriteLine("构造一个三角形"); public void SetNumberOfSides() //NumberOfSides = 5; //报错,类的普通函数中无法修改readonly常量
2、TS中的readonly:用法和C#一样,和上例不同的是,TS不支持构造函数重载,只能有一个constrator
//模仿入口函数,创建一个立即执行函数【(()=)()】 (()=> class Shape public static readonly Color:string = "red"; public readonly NumberOfSides:number; constructor(side1:number,side2:number) this.NumberOfSides = 4; console.log("构造一个矩形"); public setNumberOfSide():void //this.NumberOfSides = 5; //报错,类的普通函数中无法修改readonly常量 var s1 = new Shape(1.0,2.0); //s1.NumberOfSides = 5; //报错,实例常量无法修改 )()
3、Dart中的final:即可以在方法中使用,也可以在类中使用。
void main(List<String> args) //final可以和const一样使用 final int a1 = 1; final a2 = 2; //a1 = 3; //报错,常量一旦赋值,不能在修改 //final常量,在运行时才赋值,可以先声明,再赋值 //如果此处声明为【final a3;】,则类型推断为dynamic final int a3; a3 = 3; //体现final是运行时常量更好的例子 //const int a4 = getNum(); //报错,const不能用于运行时 final int a4 = getNum(); int getNum() return 4;
//类中使用final声明常量字段。注:如果使用了常量构造函数,所有字段必须使用final声明 class Shape static final String color = "red"; //静态常量,需要声明时初始化 final int numberOfSides; //声明实例常量字段,可以不初始化 Shape(this.numberOfSides); //使用构造函数,当创建实例时,设置final常量的值
以上是关于C#TS和Dart对比3:编译时常量和运行时常量的主要内容,如果未能解决你的问题,请参考以下文章
JVM 运行时常量池(Runtime Constant Pool)