仓颉的基础的介绍

发布于:2024-08-11 ⋅ 阅读:(139) ⋅ 点赞:(0)

1.仓颉特有的基础类型

仓颉很多基础类型和其它语言差不多,我感觉不同的类型有区间类型和本地类型以及特别的空类型。

区间类型:Range

特别的空:Nothing

本地平台类型:UIntNative,IntNative

仓颉中区分大小写,整数型Int不是int。

2.变量定义不同

其实和一些语言相同,但是和c#,Java,c++不同

定义:

let a=32;let a:Int=32;

var b=63; var b:Int=64;

用let时,a不能修改,var时,b可以修改。

定义变量a是整数型。

3.循环

仓颉中的for循环不同,使用的in。

例如:for(i in 1..10){}

注意是2个点。

4.类定义

1.构造函数

仓颉中有2种构造函数。

1.普通构造函数

普通构造函数用关键字init开头,例如:init(price:Int)。可以重载。

普通构造函数中可以用this关键字。普通构造函数可以没有。

2.主构造函数

主构造函数中的参数分为普通形参和成员形参,成员形参会自动赋值给类的同名变量。

普通形参需要放在成员形参前面。

例如:

class Ebook
{
let a:Int64;
var b:Int64;
Ebook(let a:Int64,var b:Int64)
{
}
}

2.全局变量

仓颉中可以在包中定义变量,在整个包模块中可以使用访问。

3.方法定义

仓颉中定义方法需要fun关键字

例如:

fun add(a:Int ,b:Int64):Int64

{

}

3.一个示例类(雪花算法)

package cjdemo
import std.time.*
class SnowFlake {

    /**
     * 开始时间
     */
    private var beginTimeMillis:Int64 = 1585644268888;

    /**
     * 上一次 生产id 的时间
     */
    private var  lastTimeMillis:Int64 = -1;

    /**
     * 当前时间
     */
    private var nowTimeMillis=0;

    /**
     * 机房id
     */
    private var machineRoomId:Int64;

    /**
     * 机房 id 所占 位数(总 64位)
     */
    private var machineRoomIdBits:Int64 = 5;

    /**
     * 最大 支持机房id值 即:2^5 -1 = 31  (0-31)
     */
    private var maxMachineRoomId:Int64= -1 ^ (-1 << machineRoomIdBits);

    /**
     * 机器id
     */
    private var machineId:Int64;


    /**
     * 机器id 所占 位数(总 64位)
     */
    private var machineIdBits:Int64 = 5;


    /**
     * 最大 支持机器id值 即:2^5 -1 = 31  (0-31)
     */
    private var maxMachineId:Int64 = -1 ^ (-1 << machineRoomIdBits);


    /**
     * 一毫秒内 最多允许生成id 个数 所占位数
     */
    private var sequenceBits:Int64 = 12;

    /**
     * 一毫秒内 最多允许生成id 个数
     * (2^12 - 1) = 4095 , 一毫秒内 最多允许生产 4095 个id
     * 超过该值时 进入等待,下一毫秒才可以继续生产
     * -1L ---> 2进制为:1...(62位)...1   64位都为1
     * -1L ^ (-1L << sequenceBits) = (2^12 - 1) = 4095
     */
    private var MaxSequenceNumInOneMs:Int64= -1 ^ (-1 << sequenceBits);


    /**
     * 代表一毫秒内生成的最新序号
     */
    private var sequenceNum:Int64=0;


    /**
     * 时间戳部分 需要左移 的位数;42
     */
    private var timeLeftBits = machineRoomIdBits + machineIdBits + sequenceBits;

    /**
     * 机房部分 需要左移 的位数;17
     */
    private var machineRoomLeftBits = machineIdBits + sequenceBits;

    /**
     * 机器部分 需要左移 的位数;12
     */
    private var machineLeftBits = sequenceBits;


    public SnowFlake( machineRoomId:Int64,  machineId:Int64) {
        /**
         *  判断 输入的 machineRoomId 是否在[0-31]范围内
         */
        if (machineRoomId > maxMachineRoomId || machineRoomId < 0) {
             throw  IllegalArgumentException(
                    "worker Id can't be greater than ${machineId} or less than 0");
        }

        /**
         *  判断 输入的 machineId 是否在[0-31]范围内
         */
        if (machineId > maxMachineId || machineId < 0) {

            throw  IllegalArgumentException(
                "datacenter Id can't be greater than ${machineId} or less than 0");
        }

        this.machineRoomId = machineRoomId;
        this.machineId = machineId;

    }

    public  func produceNextId():Int64 {

        /**
         *  获取 当前 时间戳
         */
        nowTimeMillis = getNowTimeStamp();

        if (lastTimeMillis == nowTimeMillis) {

            /**
             * MaxSequenceNumInOneMs:sequenceNum 的 最大值 4095(2^12 - 1)其二进制为:0000 1111 1111 1111
             *  当 sequenceNum = 4095 时(0000 1111 1111 1111) 加 1  得到-->2^12 (0001 0000 0000 0000)
             *  0001 0000 0000 0000 & 0000 1111 1111 1111  = 0
             *
             *  即,当 sequenceNum = 0 的时候 就不能继续生产id,需要等待下一毫秒才可以继续生产id,即进入等待。
             */
            sequenceNum = (sequenceNum + 1) & MaxSequenceNumInOneMs;

            /**
             * 当某一毫秒的时间,产生的id数 超过4095,系统会进入等待,直到下一毫秒,系统继续产生ID
             */
            if (sequenceNum == 0) {
                nowTimeMillis = getNowTimeStamp();
                while (nowTimeMillis == lastTimeMillis) {
                    nowTimeMillis = getNowTimeStamp();
                }
            }
        } else {
            sequenceNum = 0;
        }
        lastTimeMillis = nowTimeMillis;

        /**
         *  id = 时间戳部分(41位) | 机房id(5位) | 机器id(5位) | 1 毫秒内 id序列号(12位) = 64 二进制位 值
         */
        var a = ((nowTimeMillis - beginTimeMillis) << timeLeftBits) |
                (machineRoomId << machineRoomLeftBits) |
                (machineId << machineLeftBits) |
                sequenceNum;

        return a;

    }


    /**
     * 获取当前时间戳
     *
     * @return TimeMillis long
     */
    private func getNowTimeStamp():Int64 {
        let dur=  DateTime.now()-DateTime.UnixEpoch;
      return dur.toMilliseconds();
    }
}


网站公告

今日签到

点亮在社区的每一天
去签到