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();
}
}
个人介绍中有抖音号,欢迎关注