Go语法入门

环境

我的版本:官网最新版

IDE:使用IDEA的go插件

前言了解

  • Go 语言并不是凭空而造的,而是和 C++、Java 和 C# 一样属于 C 系。
  • 在 Go 语言出现之前,开发者们总是面临非常艰难的抉择,究竟是使用执行速度快但是编译速度并不理想的语言(如:C++),还是使用编译速度较快但执行效率不佳的语言(如:.NET、Java),或者说开发难度较低但执行速度一般的动态语言呢?显然,Go 语言在这 3 个条件之间做到了最佳的平衡:快速编译,高效执行,易于开发。
  • Go 语言是一门类型安全和内存安全的编程语言。虽然 Go 语言中仍有指针的存在,但并不允许进行指针运算。
  • Go 语言的另一个目标是对于网络通信、并发和并行编程的极佳支持,从而更好地利用大量的分布式和多核的计算机
  • Go 语言中另一个非常重要的特性就是它的构建速度(编译和链接到机器代码的速度),一般情况下构建一个程序的时间只需要数百毫秒到几秒。
  • Go 语言从本质上(程序和结构方面)来实现并发编程。
  • Go 语言使用静态类型,所以它是类型安全的一门语言,加上通过构建到本地代码,程序的执行速度也非常快。
  • Go 语言其实也有一些动态语言的特性(通过关键字 var),所以它对那些逃离 Java 和 .Net 世界而使用 Python、Ruby、PHP 和 JavaScript 的开发者们也具有很大的吸引力。
  • Go 语言被设计成一门应用于搭载 Web 服务器,存储集群或类似用途的巨型中央服务器的系统编程语言。
  • Go 语言一个非常好的目标就是实现所谓的复杂事件处理(CEP),这项技术要求海量并行支持,高度的抽象化和高性能。
  • 但是 Go 语言同时也是一门可以用于实现一般目标的语言,例如对于文本的处理,前端展现,甚至像使用脚本一样使用它。因为垃圾回收和自动内存分配的原因,Go 语言不适合用来开发对实时性要求很高的软件。

变量定义

Go 语言程序中全局变量与局部变量名称可以相同,但是函数内的局部变量会被优先考虑。

var identifier type // var name string
name := "test"
name, age, class := "lt", 18, true

常量定义

const isLive bool = true
func main() {
	const (
		a = "abc"
		b = len(a)
		c = unsafe.Sizeof(a)
	)
	print(a, b, c)
}

iota 在 const关键字出现时将被重置为 0(const 内部的第一行之前),const 中每新增一行常量声明将使 iota 计数一次    

    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //独立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢复计数
            i          //8
    )
const (
    i=1<<iota  //1
    j=3<<iota  //6
    k		   //12
    l          //24
)

取址符

	var age int = 20
	var pass *int
	pass = &age
	fmt.Printf("值为%d\n", age)
	fmt.Printf("值为%d\n", pass)

循环

    //无限循环
	for true {
		print("123")
		// break
	}
	for i := 0; i < n; i++ {
		
	}

goto

//goto的使用,goto和fori小心连用
	var i int = 0
c1:
	for i < 10 {
		if i == 5 {
			i += 1
			goto c1
		}
		print(i)
		i++
	}

简单函数调用

func main() {
	var num1, num2 int = 3, 5
	theMax := theMax(num1, num2)
	print(theMax)
}
func theMax(num1, num2 int) int {
	if num1 >= num2 {
		return num1
	} else {
		return num2
	}
}

数组训练

func main() {
	var parm = []int{0, 10, 1, 2, 3, 4, 5, 6, 7, 9}
	theMax := theMax(parm)
	print(theMax)
}
func theMax(parm []int) int {
	var maxValue int = ^int(^uint(0) >> 1)
	for i := 0; i < len(parm); i++ {
		if parm[i] > maxValue {
			maxValue = parm[i]
		}
	}
	return maxValue
}

结构体

type Book struct {
	name     string
	auther   string
	bookType string
}

func main() {
	var book Book
	book.name = "西游记"
	book.auther = "吴承恩"
	book.bookType = "玄幻"
	changedBook := change(book)
	println(changedBook.name)
	println(changedBook.auther)
	println(changedBook.bookType)

}
/**
 *加工
 */
func change(book Book) Book {
	var book1 Book
	book1.name = book.name + "1"
	book1.auther = book.auther + "1"
	book1.bookType = book.bookType + "1"
	return book1
}

切片

切片和数组,我的理解类似于Java的数组和列表的关系。Go 语言切片是对数组的抽象。

func main() {
	var number = make([]int, 3, 5)
	printSlice(number)
}

func printSlice(numbers []int) {
	println(len(numbers))
	println(cap(numbers))
	fmt.Printf("%v\n", numbers)
}
// 空(nil)切片
func main() {
	var number []int
	if number == nil {
		println("切片为空")
	}
}
func main() {
	numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8}
	fmt.Println(numbers[0:2]) //[0 1]
	fmt.Println(numbers[:3])  //[0 1 2]
	fmt.Println(numbers[4:])  //[4 5 6 7 8]
	//追加
	newNum := append(numbers, 9)
	fmt.Println(newNum) //[0 1 2 3 4 5 6 7 8 9]
	//copy
	copyNum := make([]int, len(numbers), (cap(numbers))*2)
	copy(copyNum, numbers)
	fmt.Println(copyNum) //[0 1 2 3 4 5 6 7 8]
}

map

func main() {
	countryCapitalMap := make(map[string]string)
	countryCapitalMap["France"] = "巴黎"
	countryCapitalMap["Italy"] = "罗马"
	countryCapitalMap["Japan"] = "东京"
	countryCapitalMap["India"] = "新德里"
	for country := range countryCapitalMap {
		fmt.Println(country, "首都是", countryCapitalMap[country])
	}
	capital, ok := countryCapitalMap["France"]
	fmt.Println(capital) //巴黎
	fmt.Println(ok)      //true

	// 删除
	delete(countryCapitalMap, "India")
	fmt.Println(countryCapitalMap)

	//for country := range countryCapitalMap {
	//	fmt.Println(country, "首都是", countryCapitalMap[country])
	//}
}

类型转换

go 不支持隐式转换类型

接口案例

type phone interface {
	call()
}

type Aphone struct {
}
type Bphone struct {
}

func (receiver Aphone) call() {
	fmt.Printf("Aphone调用\n")
}
func (receiver Bphone) call() {
	fmt.Printf("Bphone调用\n")
}
func main() {
	var apone Aphone
	apone.call()
	var bphone Bphone
	bphone.call()
}

异常案例

type DivideError struct {
	dividee int
	divider int
}

func (de *DivideError) Error() string {
	strFormat := `
    Cannot proceed, the divider is zero.
    dividee: %d
    divider: 0
`
	return fmt.Sprintf(strFormat, de.dividee)
}
func Divide(varDividee int, varDivider int) (result int, errorMsg string) {
	if varDivider == 0 {
		dData := DivideError{
			dividee: varDividee,
			divider: varDivider,
		}
		errorMsg = dData.Error()
		return
	} else {
		return varDividee / varDivider, ""
	}
}
func main() {

	// 正常情况
	if result, errorMsg := Divide(100, 10); errorMsg == "" {
		fmt.Println("100/10 = ", result)
	}
	// 当除数为零的时候会返回错误信息
	if _, errorMsg := Divide(100, 0); errorMsg != "" {
		fmt.Println("errorMsg is: ", errorMsg)
	}

}

并发

用go修饰,输出没有固定先后顺序。因为它们是两个 goroutine 在执行

func main() {
	go sleep("hello")
	sleep("你好")
}
//hello
//你好
//你好
//hello
//hello
//你好
//你好
//hello
//hello
//你好
func sleep(s string) {
	for i := 0; i < 5; i++ {
		time.Sleep(500 * time.Millisecond)
		fmt.Println(s)
	}
}

通道

通道可用于两个 goroutine 之间通过传递一个指定类型的值来同步运行和通讯。

func sum(s []int, c chan int) {
        sum := 0
        for _, v := range s {
                sum += v
        }
        c <- sum // 把 sum 发送到通道 c
}

func main() {
        s := []int{7, 2, 8, -9, 4, 0}

        c := make(chan int)
        go sum(s[:len(s)/2], c)
        go sum(s[len(s)/2:], c)
        x, y := <-c, <-c // 从通道 c 中接收

        fmt.Println(x, y, x+y)
}

缓冲通道

带缓冲区的通道允许发送端的数据发送和接收端的数据获取处于异步状态,就是说发送端发送的数据可以放在缓冲区里面,可以等待接收端去获取数据,而不是立刻需要接收端去获取数据。

func main() {
    // 这里我们定义了一个可以存储整数类型的带缓冲通道
        // 缓冲区大小为2
        ch := make(chan int, 2)

        // 因为 ch 是带缓冲的通道,我们可以同时发送两个数据
        // 而不用立刻需要去同步读取数据
        ch <- 1
        ch <- 2

        // 获取这两个数据
        fmt.Println(<-ch)
        fmt.Println(<-ch)
}

参考

https://github.com/unknwon/the-way-to-go_ZH_CNicon-default.png?t=M3C8https://github.com/unknwon/the-way-to-go_ZH_CN

Go 语言教程 | 菜鸟教程Go 语言教程 Go 是一个开源的编程语言,它能让构造简单、可靠且高效的软件变得容易。 Go是从2007年末由Robert Griesemer, Rob Pike, Ken Thompson主持开发,后来还加入了Ian Lance Taylor, Russ Cox等人,并最终于2009年11月开源,在2012年早些时候发布了Go 1稳定版本。现在Go的开发已经是完全开放的,并且拥有一个活跃的社区。 Go 语言特色 简洁、快速、..https://www.runoob.com/go/go-tutorial.html 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值