β

区块链学习-golang数组、map、函数、类

行者无疆 155 阅读

数组/切片

数组声明:

普通声明:
var arr = [5]int{} // 长度固定为5,不可扩展,{}中为初始值,默认为0  
arr := [5]string{"a", "b", "c", "d"}  
var arr [5]int // [0, 0, 0, 0]
make关键字声明数组切片:  
var arr = make([], 2, 4) // 长度 len(arr) 为2,容量 cap(arr) 为4,长度决定存储量,容量不够时翻倍  
arr := make([], 1, 1)  
arr = append(arr, 1)    // len(arr)=1 cap(arr)=1  
arr = append(arr, 2)    // len(arr)=2 cap(arr)=2  
arr = append(arr, 3)    // len(arr)=3 cap(arr)=4
截取、拼接数组:
arr1 :=[]int{1, 2, 3, 4, 5, 6}  
arr2 :=[]int{7, 8, 9}  
arr1[:3] // 等价于arr1[0:3] => [1, 2, 3]  
arr1[3:] // 等价于arr[3:5] => [4, 5, 6]  
arr1 = append(arr1, arr2...) // arr1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
二维数组:
var arr = [2][2]int{} // [[0, 0], [0, 0]]
遍历:
for index, value := range arr {  
    fmt.Println(index, value)
}

区别于 javascript: * 数组中只能存储相同类型的值 * 只有make关键字声明的切片长度可变

map

map字典,对应于javascript中的对象,即为键值对的集合

普通声明方式:
var map = map[string]string{  
    "name": "ludis",
    "age": "18",
}
map := map[int]string{  
: "first",
: "second",
}
make关键字声明:  
var map = make(map[string]string) // map == nil  
map["name"] = "ludis" // 赋值  
delete(map, "name")   // 删除  
// 判断是否存在某属性
if val, ok := map["name"]; ok {  
    fmt.Println(val)
    fmt.Println(ok)
}
遍历:
for _,value := range map{  
    fmt.Println(value)
}

函数

三种函数声明方式:
func function(name string, age int) string{  
    reutrn name+string(int)
}
var function = func(name string, age int) string{  
    reutrn name+string(int)
}
function := func(name string, age int) string{  
    reutrn name+string(int)
}
函数类型为:(去掉函数名及变量名)
func(string, int) string
、通过func关键字声明的为全局函数,等同于用var声明的全局函数,不能再函数体内用func声明函数  
、在函数体内声明局部函数的方法为 := 简写方式  
、函数声明会提升,变量声明不会提升
回调函数/函数作为参数、函数作为返回值:
func getUserName(name string, f func(name string, age int)){  
    f(name)
}
func getUserName(name string) func(string){  
    return func(name string){
        fmt.Println(name)
    }
}

类与继承、复合、重写

类的定义:通过关键字 type 定义
type Animal struct {  
    age int
    weight float64
}
类的方法定义:
func (animal *Animal) setAge(age int){  
    animal.age = age
}
func (animal *Animal) getWeight() float64{  
    return animal.weight
}
// 通过 (animal *Animal) 将函数与类绑定,使其成为类的方法
// (animal Animal) 不加地址符时为深拷贝,加地址符为浅拷贝
创建类的对象:
animal := Animal{18, 66.6}  
animal.setAge(8)    // animal.age = 8  
fmt.Println(animal.getWeight()) // 66.6
复合:(汽车有四个轮子、有品牌;轮子有半径。汽车复用轮子类)
type Wheel struct {  
    r float
}
type Car struct {  
    wheels [4]intWheel
    brand string
}
wheel := Wheel{66.6}  
wheels := [4]Wheel{wheel, wheel, wheel, wheel}  
car := Car{  
    wheels: wheels,
    brand: "Tesla",
}
fmt.Print(car)
继承:(动物、狗)
type Animal struct {  
    age    int
    weight float64
}
func (a *Animal) backAgeAndWeight() (int, float64) {  
    return a.age, a.weight
}
// 方法重写
func (d *Dog) backAgeAndWeight() (int, float64) {  
    return d.age, d.weight
}
type Dog struct {  
    // animal Animal -> Animal 直接继承为自有属性
    Animal
    name string
    age  int
}
dog := Dog{  
    Animal: Animal{5, 6},
    name:   "二哈",
    age:    18,
}
// 继承
fmt.Println(dog.age)  
// 复合->模拟继承
fmt.Println(dog.Animal.weight)
// var animal Animal = Dog{}
// 父类的指针指向子类的对象 -> 多态
// go模拟继承,非正真的继承 dog.age != dog.Animal.age,通过复合模拟真正的继承
fmt.Println(dog.Animal.backAgeAndWeight())  
fmt.Println(dog.backAgeAndWeight())  

go语言中的继承并非正真意义上的继承,而是通过复合的方式模拟继承,当子类继承父类后,子类创建的对象中,包含一个隐藏的父类对象,其中包括父类的属性及方法。当在子类创建的对象中定义重名的属性/方法时,并不会修改父类对象中的属性/方法,而是直接在子类创建的对象上添加,类似javascript中的原型链,当查询对象的属性/方法时,优先在对象上查找,未找到时才会去继承自父类的对象上查找。所以说golang的继承是伪继承。

作者:行者无疆
Welcome to blog
原文地址:区块链学习-golang数组、map、函数、类, 感谢原作者分享。