【GO】基础速成

简单介绍一下go好处

  • 编译语言,可以提前报错
  • 同时又有python的一些优点,
  • 自带多线程

开始学习

学习网站:学习网站

包含:字符串、整型、浮点型、布尔型等等
字符串可以 + 进行拼接。
需要注意的是布尔型在go里面不自动转化为int类型,不认为 true为1 false为0。布尔型是布尔型,int类型就是int类型,不可以转化

变量与常量

// 正常声明变量
// var关键字,表示要声明变量,后面加变量名
// 变量名之后加变量类型
// 最后附上初始化的值
var a int = 1
// 省略版声明变量
// 但只能作为局部变量
// 并且必须初始化
// 会自动根据初始化的值为变量设置类型
b := 1

// 能var的地方就能const
// 数值型常量没有确定的类型,直到被给定某个类型,比如显式类型转化。
const n = 123

循环

// 好像只有for 循环
// while的写法
i := 1
for i <= 3 {
	i = i + 1
}

// 正常for写法
for i := 0; i <= 2 ; i ++{
	//
}

// 死循环
// 只能break掉
// 支持break 与 continue语句
for {
}

if-else & switch


// 没啥好说的
if 7%2 == 0 {

} else if  condition {

} else {

}

// switch 有些不一样
// c会继续自动往下执行
// go是你必须显示说明语句才会往下一个case执行
// 所以不需要添加break语句
switch i {
case 1:
	// 1干啥
case 2:
	// 2干啥
default:
	// 最后一个情况干啥
}

数组

一般不用数组,因为跟C数组一样,固定死,不能动态改变

	var a [5]int
	b := [5]int{1, 2, 3, 4, 5}
	c := len(b)

高级数组slice

一般用这个,类似vector的东西吧

// 声明一个slice
// make语句,第一个表示类型,第二个表示个数
s := make([]string, 3)
// 支持len()检测长度
// 支持copy
// 支持append
s = append(s, "d")
s = append(s, "e", "f")
fmt.Println("apd:", s)
c := make([]string, len(s))
copy(c, s)
fmt.Println("cpy:", c)

map

// map声明
// 使用make,中括号里面写key的type
// 后面跟上value的type
m := make(map[string]int)

range

类似for-each

nums := []int{2,3,4}
sum := 0
// 遍历数组,slice类似
// 第一个返回下标,第二个返回值
for i, num := range nums{
	sum += num
}

// 遍历map
// 第一个返回key, 第二个返回value
m := make(map[string]int)
for key, value := range m {
}

函数

变量数组这些声明都挺抽象的,函数声明更抽象

// func关键字表示要声明一个函数
// 后面跟函数名
// 后面跟形参,先形参名后面跟类型
// 形参写完最后写函数返回值的类型,可以多个
// 够抽象吧?
func plus(a int, b int) int {
	return a+b
} 

// 多返回值
func mul(a int, b int) (int, int){
	return 3,7
}

// 这是对的方式
func xxxx {

}

// 这个是错的方式
func xxx
{

}

还有一个需要极其注意的点是,go语言可以不加封号,是因为在编译时候编译器会帮你加上
前提是你括号写的方式要写对

// 变参函数,也就是说可以输入参数个数不固定,也可以是数组
func sum(nums ...int) {
    fmt.Print(nums, " ")
    total := 0
    for _, num := range nums {
        total += num
    }
    fmt.Println(total)
}
func main(){
	sum(1,2)
	sum(1,2,3)
	nums := []int{1,2,3,4}
	sum(nums...)
}

指针

没想到吧?go这沙比还支持指针,而且这个指针跟c感觉差不多。感觉这个语言是个缝合怪

// 直接copy了
package main

import "fmt"

func zeroval(ival int) {
    ival = 0
}

func zeroptr(iptr *int) {
    *iptr = 0
}

func main() {
    i := 1
    fmt.Println("initial:", i)

    zeroval(i)
    fmt.Println("zeroval:", i)

    zeroptr(&i)
    fmt.Println("zeroptr:", i)

    fmt.Println("pointer:", &i)
}

// 最后的result
initial: 1
zeroval: 1
zeroptr: 0
pointer: 0x42131100

结构体

// 结构体声明
// type struct关键字中间加结构体名称
// 里面写成员变量
// 先名称后类型
type person struct {
	name string
	age int
}

// struct好像没有构造函数
// 所以好像一般使用类似工厂模式写一个方法
// 感觉有点呆
func newPerson(name string, age int) *person {
// 构造结构体对象的各个方法
	// 1.按照顺序默认对应
	p := person{name, age}
	// 2.指明赋值
	p := person{name: name, age: age}
	// 返回指针
	return &p
}

func main(){
	s := newPerson("Bob", 23)

	// 还有一个点跟C有点不一样
	// go的.运算符可以自动解指针,不需要加*了
	fmt.Println(s.age)
}

// go 可以对结构体编写成员函数
// func 后面跟括号,里面第一个写变量名 第二个写类型
// 一般要写成指针形式,不然调用函数修改的是你这个对象的拷贝
// 第一个变量就是调用自己这个实例,类似于this或者self
// 所以如果习惯java可以第一个叫this,习惯python可以写self
// 可以自己去试试看
// 加了这一项表名这个方法是person的成员函数
// 由于set方法不需要返回值,所以参数列表之后为空
func (p *person) setAge(age int) {
	p.age = age
}

后面接口啥的就不写了,差不多到这基本大体上写写一般程序够用了。
面向对象还要学学继承跟多态,GO语言这两个有点抽象
摆烂先懒得写,后面补

继承

哥们回来补作业啦
go的继承比较奇怪,他不用JAVA或者python那种显示关键字进行继承,而是用组合

// 先说说go语言特性
// 在struct可以编写匿名字段
// 也就是说不写名称,只写类型
// 但每一个struct的一个类型只能有一个匿名
type demo struct{
	int
	float32
}
d := demo{}
// 直接这样就可以访问匿名字段
d.int

// 再说说“继承”也就是组合
type Animal struct {
}

func (self *Animal) Eat() {
	fmt.Println("Animal eating....")
}

type Cat struct {
	// 这里直接用匿名
	// 是为了如果需要访问父类
	// 只需要.Animal就行
	// 不然到时候起个名字
	// 调用父类还都是乱七八糟的名字
	Animal
}

// 重写方法
func (self *Cat) Eat() {
	// 这里就可以通过组合访问父类的字段
	// 或者方法
	// 这里其实就有点类似于java的super
	self.Animal.Eat()
	fmt.Println("Cat eating...")
}

// go在调用方法时候会自己判断
// 有没有重写方法
// 有就调用最新的
// 没有就调用父类的
// 自己试试
func main() {
	cat := Cat{}
	
	cat.Eat()
}

接口

go的接口好像比较简单一些些,就弄个接口,没有什么显示的关键字关联关系,只要实现了这个接口里面的所有方法,就算实现了这个接口,完了就可以用接口实现多态。
go好像不用继承实现多态?我不懂是不是这样,有懂哥麻烦评论区说说呗?感激不尽。

// 写个接口creature
// 接口俩方法一个叫一个跑
type creature interface {
	run() string
	sound() string
}

type Cat struct{}
type Human struct{}

// 猫实现接口俩方法
func (self *Cat) run() string {
	return "Cat running..."
}

func (self *Cat) sound() string {
	return "miao~"
}

// 人实现接口俩方法
func (self *Human) run() string {
	return "Human running..."
}

func (self *Human) sound() string {
	return "wocao!"
}

func main() {
	// 完了之后开个接口类型切片
	// 初始化一下
	c := make([]creature, 2)
	c[0] = &Cat{}
	c[1] = &Human{}
	
	// 发现可以实现多态
	for _, v := range c {
		fmt.Println(v.run())
		fmt.Println(v.sound())
	}
}

完了之后还有一个空接口,interface{}。这玩意类似java的obj。谁都是他的子类就这么理解应该就行了。
所以参数里面写interface{}这个类型就说明他可以接收任意类型的参数。
那么如何动态的检测这个interface{}类型具体是什么类型呢?

// 用这个类型断言机制
func main() {
	// 声明a为interface类型,并且初始化为一个string
	var a interface{}
	a = "i am a string"
	// 这个变量名.再加括号里面加类型就是类型断言
	// 返回值有两个
	// 第一个是类型断言之后的值
	// 第二个表示是否是这个类型
	v, err := a.(string)
	if err != false {
		fmt.Println(v)
	} else {
		fmt.Println("im not string")
	}
	// 还有一个是变量名.(type)返回的只有一个值,是这个变量的具体类型
	// 但必须结合switch语句进行使用
	// copy 别人代码
	switch v := x.(type) {
	case string:
		fmt.Printf("x is a string,value is %v\n", v)
	case int:
		fmt.Printf("x is a int is %v\n", v)
	case bool:
		fmt.Printf("x is a bool is %v\n", v)
	default:
		fmt.Println("unsupport type!")
	}

好了更完了继承接口多态。就可以去写OOP了。
继续鸽。
还没到GO最特别的,也就是并发那一块跟channel。
继续摆,过几天再学再写写

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值