Yak之数据类型

admin 2022年9月28日13:46:35安全开发评论9 views3995字阅读13分19秒阅读模式

0x01 基本类型

对比C语言的基本数据类型

C语言:int、char、float(保留小数点后7位,4个字节)、double(保留小数点后15位,八个字节)

Yak语言:int、float(类似于Go语言中float64,等价于C语言中的double类型)、string、byte、bool、var

代码理解(官方解释代码):

a = 1 // 整数类型

b = "CV is handsome" // string 类型

c = true // bool 类型

d = 1.0 // float 类型

e = 'c' // byte 类型,理解为占一个字节,同C语言的char类型

f = var // f 为一个兼容类型,意思就是遇到值为整型,则就是整型;遇到其他类型同理。

强制转换

type(value)

代码理解(官方解释代码):

a = int(1.2)  //a的值为1,类型为int型

b = 1.2 //b的值为1.2,类型为float型

c = int(b) //c的值为1,类型为int型

0x02 复合类型

1)slice类型

官方解释:用于以列表的形式存储元素的数据类型 (等效于 Python 的 list),同 Golang 中的 slice。

个人理解:类似于数组。

代码理解(以下均为官方解释代码):

创建slice类型

b = [1, 2.3, 5]         // 创建一个 []float(因为有一个float类型,所以默认为float数组)

c = ["a", "b", "c"]     // 创建一个 []string

d = ["a", 1, 2.3]       // 创建一个 []var (等价于 Go 语言的[]interface{})

e = make([]int, 3, 3)   // 创建一个 []int,并将长度设置为 3,容量设置为 3

f = make([][]int, 3, 3) // 创建一个 [][]int,并将长度设置为 3,容量设置为 3

g = []byte{1, 2, 3}     // 创建一个 byte slice,并初始化为 [1, 2, 3]

h = []byte(nil)         // 创建一个空 byte slice

总结官方代码:

make()函数创建某种类型,[]创建数组也可以说是列表;如果[]没有定义类型,则会自动判断类型,如果有整数、小数、字符等,类型则是var型;如果有整数和小数,类型则是float型,其原因作者个人认为与C语言中相同,如果有大字节,统一按照大字节类型定义。比如,int类型如果是2字节,float如果是4字节,在定义数组时,同时出现了int类型和float类型,则默认按照4字节处理,这时会将int类型转换成float类型。

科普一下,为什么在int类型和float类型同时出现在一个运算式中,结果为float型。其实这里注意一点,如果是float类型的数据转换成int类型,肯定要丢失数据。解释:假设float为8字节,int为4字节,float转换成int,则需要丢失4字节的空间,所以在很多语言中,就算int和float的字节相同,也会转换成float型,已经成为一个约定俗成的规则了。

添加元素

a=append(a,1,2,3)

append(target,value...)函数作用是添加元素。

a = append([1,2,3], 5,6,7)

length = len(a)

println("len(a): ", length)

capValue = cap(a)

println("cap(a): ", capValue)

// OUTPUT:
//   len(a): 6
//   cap(a): 6

len()函数获取目标变量元素个数,cap()函数获得目标变量容量。

复制

copy(sliceA,sliceB)把B中的元素复制到A中

a = [1,2,3]
b = [4,5,6,7,8]
copiedCount = copy(a, b)
println("copy(a, b) returns ", copiedCount)
println("slice a now: ", a)

// OUTPUT:
//   copy(a, b) returns 3
//   slice a now: [4 5 6]

按索引获取数组元素,与python中的语法类似。

a = [1,2,3,4,5,6,7,8]
b = a[4:6]
c = a[:5]
d = a[3:]
index1 = a[1]
index2, index3 = a[2], a[3]

println("b: ", b)
println("c: ", c)
println("d: ", d)
println("a[1]: ", index1)
println("a[2]: ", index2)
println("a[3]: ", index3)

//运行结果:
//b: [5 6]
//c: [1 2 3 4 5]
//d: [4 5 6 7 8]
//a[1]: 2
//a[2]: 3
//a[3]: 4

2)map类型

官方解释:用于以键值对的形式存储数据的结构(等效于 Python 中的 dict),同 Golang 中的 map。

个人理解:可以参考JSON数据。

代码理解(以下均为官方解释代码):

创建map变量

// 得到 map[string]int 类型的对象
a = {"a": 1, "b": 2, "c": 3}
// 得到 map[string]float64 类型的对象
b = {"a":1,"b":2.3,"c": 3}
// 得到 map[int]string 类型的对象
c = {1: "a", 2: "b", 3: "c"}
// 得到 map[string]interface{} 类型的对象
d = {"a": "hello", "b": 2.0, "c": true}
// 创建一个空的 map[string]int 类型的对象
e = make(map[string]int)
// 创建一个map[string]map[string]int 类型的对象
f = make(map[string]map[string]int)
// 创建一个 map[string]int16 类型的对象
g = map[string]int16{"a": 1, "b": 2}
// 创建一个 map[string]interface{}
x = {}
// 创建一个 map[interface{}]interface{}
x = make(map[var]var)

map的特征{key:value...},所以创建特征符合map类型,则创建的变量就为map类型。

map的基本用法

a = {"a": 234, "b": "sasdfasdf", "ccc": "13"}      // 我们创建一个 map[var]var

n = len(a) // 取 a 的元素个数
println("len(a): ", n)
// OUTPUT: len(a): 3

x = a["b"] // 取 a map 中 key 为 "b" 的元素
println(`a["b"]: `, x)
// OUTPUT: a["b"]: sasdfasdf

a.noSuchKey // 如果取一个不存在的 key,直接通过 .keyName 调用则会报错,退出程序
// OUTPUT:
// [ERRO] 2021-05-25 20:38:04 +0800 [default:yak.go:100] line 58: member `noSuchKey` not found

// 当然,我们也可以把拆包解包用在 map 中
a["e"], a["f"], a["g"] = 4, 5, 6 // 同 Go 语言
a.e, a.f, a.g = 4, 5, 6 // 含义同 a["e"], a["f"], a["g"] = 4, 5, 6

// 如果你想要删掉 map 中的某个元素
a = {"a": 123, "b": 1345, "c": 999}
println("a.b: ", a.b)
delete(a, "b")
println("NOW map a: ")
dump(a)
/*
a.b: 1345
NOW map a:
(map[string]int) (len=2) {
(string) (len=1) "a": (int) 123,
(string) (len=1) "c": (int) 999
}
*/

3)chan类型

官方解释:Yak 与 Golang 特有的复合数据类型,通过 make(chan <T>) 创建,<T> 为这个 chan 数据通道传输的数据类型,可以类比为 Python 中的 Queue。

个人理解:将chan理解成一个仓库,进行的操作都是数据的出仓和入仓,在上一节课中有讲到。其实chan是建立一个缓冲区。

创建chan类型

ch1 = make(chan bool, 2)        // 得到 buffer = 2 的 chan bool
ch2 = make(chan int) // 得到 buffer = 0 的 chan int
ch3 = make(chan map[string]int) // 得到 buffer = 0 的 chan map[string]int

这里需要注意的是,chan类型只能通过make()函数创建,与Go语言用法相同。

基本用法

/*创建一个 chan var*/
ch1 = make(chan var, 4)
ch1 <- 1
ch1 <- 2

// 一通操作
n = len(ch1) // 取得chan当前的元素个数
m = cap(ch1) // 取得chan的容量
v = <-ch1 // 从chan取出一个值
close(ch1) // 关闭chan,被关闭的chan是不能写,但是还可以读(直到已经写入的值全部被取完为止)
v1 = <- ch1
v2 = <- ch1

// 查看操作的结果和特性
println("len(ch1): ", n)
println("cap(ch1): ", m)
println("<-ch1 执行第一次: ", v)
println("<-ch1 执行第二次: ", v1)
println("<-ch1 执行第三次: ", v2)

//运行结果
//len(ch1): 2
//cap(ch1): 4
//<-ch1 执行第一次: 1
//<-ch1 执行第二次: 2
//<-ch1 执行第三次: undefined


课件参考来源于Yak官网,最后想要学习Yak语言的大佬可以关注微信公众号:乌托邦安全团队,后面会持续更新Yak相关的学习经验。

公众号输入Yak教程第二课,获取当前课件。

作者:CV


原文始发于微信公众号(乌托邦安全团队):Yak之数据类型

特别标注: 本站(CN-SEC.COM)所有文章仅供技术研究,若将其信息做其他用途,由用户承担全部法律及连带责任,本站不承担任何法律及连带责任,请遵守中华人民共和国安全法.
  • 我的微信
  • 微信扫一扫
  • weinxin
  • 我的微信公众号
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2022年9月28日13:46:35
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                  Yak之数据类型 http://cn-sec.com/archives/1321311.html

发表评论

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: