【Golang】入门 数据类型 以及 并发

1.go语言申明一个变量:

  • 最简单的方法
// var + 变量名 + type
var goVari type
  • 自动赋于类型的懒人方法
// goVari 自动会定义成int类型
goVari := 2

var goVari int
goVari =2

// goVari 自动定义成string类型
goVari := "str"
  • 我们也可以一次性申明多个变量
var goVari1, goVari2, goVari2 int 
goVari1, goVari2, goVari2 = 1, 2, 3

//或者
var goVari1, goVari2, goVari2 = 1, 2, 3
goVari1, goVari2, goVari2 := 1, 2, 3

2.Go中数据类型

简单的数据类型

  • 布尔型 bool
  • 数字类型 int,float32,float64,complex64,complex128
  • 字符串类型: string

派生类型

  • 指针类型 Pointer
    指针跟C++里面的指针是差不多的,首先我们要知道在go里面取地址符也是&,如果输出&goVari就是输出这个变量的在内存中的地址。
    那么指针就是用来指向一个值的内存地址,其实为什么Java里面没有指针,其实这个大家可以去看下Java的浅拷贝和深拷贝,一般而言,在Java中如果不是Clone的话,相同类型的变量赋值都是直接指向变量地址的,这样的话一个变量变化了,另一个变量也会变化,而指针就是这个作用。
var a int = 20
//申明一个可以指向int类型的指针
var ip *int
//ip指向a的内存地址,ip的地址=a的地址,ip要取值的话也是取a地址的值
ip = &a
a++
fmt.Printf(*ip, a)
// 21 21
  • 数组类型
    数组就比较简单了,但是相比Java中的数组,Go的数组不仅有静态数组,而且也沿用了C++中的动态数组,可以自动增加数组容量,这个类型被称为切片类型,在下面有讲到
//静态数组申明和调用
var goVari [3]int
//如果需要初始化
var goVari = [3]int{1,2,3}
goVari := [3]int{1,2,3}

//取值
goVari2 = goVari[0]  // = 1
  • 结构化类型 struct
//定义一个结构体
type book struct{
	name string
	author string
	book_id int
}
func main(){
	var book1 book
	boook.name = "Go语言学习"
}

看到结构体,是不是有点像Java中的类,那么Java类中肯定不止变量了,还应该有很多方法,在Go中也是可以有方法的。

type iPhone struct{
	price float32
	color string
	id string
}
//定义iPhone的方法
func (iphone iPhone) call(){
	fmt.Println("This call is from %s", iphone.id)
}
//调用call函数
var iph iPhone
iph.call()
  • 管道类型 chan 用于并发

  • 切片类型 Slice
    切片类型是对数组的抽象,可以被看作是动态数组,长度可以改变的数组,当然

//[]不定义长度来申明切片
var slice1 []int
slice1 := []int{1,2,3}

//通过make来定义切片, len为切片的初始长度
slice2 := make([]int,len)
  • 接口类型 interface
    Go的接口和Java的接口差不多的意思,申明几个方法,然后让其他函数去继承实现,这个可以配合struct类型来使用,因为struct本身是不能申明函数的,所以在外面申明的时候可以去实现某个接口
type phone interface{
	call()
	getname() string
	getprice()(float32, float32, float32)
}
type HUAWEI struct{
	name string
	price_low float32
	price_mid float32
	price_high float32
}
func (huawei1 HUAWEI) call(){
	fmt.Println("This call is from HUAWEI")
}
func (huawei1 HUAWEI) getname()string{
	return huawei1.name
}
func (huawei1 HUAWEI) getprice()(float32, float32, float32){
	return huawei1.price_low,huawei1.price_mid,huawei1.price_high
}
//当然如果我们有其他的struct也可以直接实现接口phone中的方法

//调用的时候
var huawei HUAWEI
...
huawei.getprice()
  • Map类型
//map类型申明
var maps map[int]string //这个时候是nil的也就是空的,这个时候是不能放入键值对的,需要初始化
maps = make(map[int]string

//所以简化点就是
maps := make(map[int]string)

//map赋值
maps[1] = "go1"
maps[3] = "go2"

  • range关键字
    range关键字用于枚举数组或者其他类型中的每个元素
//枚举数组
num := []int{1,2,3}
// _ 表示num的下标,range会返回两个结果,index和num,这里_表示我们不需要index
for _, num := range nums
{
	fmt.Println(num)
}

//枚举map
maps := map[string]string{"a":"apple","b":"banana"}
for k,v := range maps
{
	fmt.Printf("%s -> %s", k, v)
}

3.Go的并发

很多地方从Java转go,有一部分原因是因为Go语言的高并发性能,所以了解go的并发实现也是很重要的。
Go中的并发都是通过goroutine关键字来支持的,goroutine是轻量级线程,其实他还有另外一个名字叫协程,这些协程是Go高并发,高性能的前提条件。

goroutine

  • 语法格式
//开启一个goroutine来执行func1
go func1(x,y,z)
  • example:
func say(s string) {
        for i := 0; i < 5; i++ {
                time.Sleep(100 * time.Millisecond)
                fmt.Println(s)
        }
}

func main() {
        go say("world")
        go say("hello")
}

//output
world
hello
hello
world
world
hello
hello
world
world
hello

通道 channel

通道其实跟操作系统中的管道差不多,用来存储两个goroutine之间的通信数据,可以实现异步通讯,比如我routine1将数据先放入channel中,routine2并不一定是第一时间去channel取数据,而是可以在需要的时候再去取数据。

//申明一个channel,len可以设定通道的缓冲区大小
ch := make(chan intlen)

//放数据
ch <- v

//取数据,赋值给getData
getData := <- ch

// range关键字遍历通道
for i := range ch{
	fmt.Printf(i)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值