C#、TS和Dart对比3:编译时常量和运行时常量

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、理清一下数据的命名习惯

本地变量、本地常量、成员变量、成员常量、实例变量、静态变量、字段、属性......不同开发语言,对定义在方法和类中的数据有不同的命名方式。在学习常量之前,先理清一下。以下仅是我的习惯,大家可以参考一下:

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声明常量字段 class Shape { static final String color
= "red"; //静态常量,需要声明时初始化 final int numberOfSides; //声明实例常量字段,可以不初始化 Shape(this.numberOfSides); //使用构造函数,当创建实例时,设置final常量的值 }

 

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6