go 入门

go 入门,第1张

go 入门

本文以 https://tour.golang.org/welcome/1 为主要参考

go和python有点像,是没有分号的。

go中需要 定义package,没有默认包

package main //必须有

import ( // 小括号
	"fmt"  
	"math/rand"
)

// 函数申明时 ,func
func swap(x, y string) (string, string) {// 多返回值
	return y, x
}

func split(sum int) (x, y int) {
	x = sum * 4 / 9
	y = sum - x
	return  // 直接返回 x y
}

func main() {  // 方法名后写返回值,省略则为Void

// 
	fmt.Println("My favorite number is", rand.Intn(10)) // 无分号
	//包名后方法名 首字母大写   方法名大写,则可以再其他包中调用,小写则不行
   // 变量声明
   var x int
   x = 5
   var y = 10
   var x,y int = 10,15
   x ,y := 1,10
   fmt.Println("x type %T", x) //x type int
}

没有初始化的变量会被赋值为零值。 数值型为0,bool 为fasle ,string为“”

go没有默认的类型转换,所有必须强转

float64(1+2)
运行go
# 1
go run hell.go

# 2
go build hell.go# 构建二进制文件
./hell # 运行
常量作为枚举
    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
    )
     fmt.Println(a,b,c,d,e,f,g,h,i)
     //       0 1 2 ha ha 100 100 7 8

const 常量由于再声明时就需要初始化,所以可以不写类型

循环 和判断

所有的大括号都不能省略

// for each
for index, value := range slice {}
for i := range slice {}
for _, v := range slice {}

// 标准for
	sum := 0
	for i := 0; i < 10; i++ {
		sum += i
	}
	fmt.Println(sum)

// while
	sum := 1
	for sum < 1000 {
		sum += sum
	}
// 无限循环
	for {
	}
// if
	if x < 0{
	}
defer

可以认为是try catch 中的finally,对整个函数try catch,最后无论是正常执行还是异常退出,都去执行defer

func main() {
	fmt.Println("counting")

	for i := 0; i < 10; i++ {
		defer fmt.Println(i)
	}

	fmt.Println("done")
}



counting
done
9
8
7
6
5
4
3
2
1
0

更多见 https://blog.go-zh.org/defer-panic-and-recover

指针
	i, j := 42, 2701

	p := &i         // 指向 i
	fmt.Println(*p) // 通过指针读取 i 的值
	*p = 21         // 通过指针设置 i 的值
	fmt.Println(i)  // 查看 i 的值
结构体 和方法
type Vertex struct {
	X int
	Y int
}

func change(v Vertex){
	v.X =10 // 访问时可以忽略*
	(*v).X =10 // c中指针访问
	fmt.Println(v.X) // 10
}

func change1(v *Vertex){
	v.X =10
	fmt.Println(v.X)
}

func main() {
	v := Vertex{1, 2}
	v.X = 4
	fmt.Println(v.X) // 4
	change(v)
	fmt.Println(v.X)	// 4
	change1(&v) 
	fmt.Println(v.X)	// 10
}

结构体初始化
可以只初始化部分参数,类似python函数中部分有默认值的参数可以省略。toString也不需要搞,自动带一个

var (
	v1 = Vertex{1, 2}  // 创建一个 Vertex 类型的结构体
	v2 = Vertex{X: 1}  // Y:0 被隐式地赋予
	v3 = Vertex{}      // X:0 Y:0
	p  = &Vertex{1, 2} // 创建一个 *Vertex 类型的结构体(指针)
)

func main() {
	fmt.Println(v1, p, v2, v3)
	// {1 2} &{1 2} {1 0} {0 0}
}

go没有类,但可以给结构体写方法

// 方法,输入即可以是 值也可以是指针,区别同传值和传指针
func (v *Vertex) Scale(f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}
// 必须传入指针,即&p
func ScaleFunc(v *Vertex, f float64) {
	v.X = v.X * f
	v.Y = v.Y * f
}

go中nil对象也能调用方法,古再方法中需要自行判断

JAVA中父的toString方法,go中使用String

// 结构体转string
func (p Person) String() string {
	return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
}
数组切片

数组传递时是传值,即copy,和JAVA中有明显区别。如果要传递数组的话,可以考虑传指针或传切片。

数组。go中数组和其长度是绑定的,如果函数要返回一个数组,那么再返回值中必须指明数组的大小。

//数组创建
var a [10]int
return int[10]int{}
// 返回数组
func get() [10]int{
	return [10]int{}
}
//数组和切片还是有区别的
func Pic(dx, dy int) [][]int{
       var img [10][10] int
	   return img
}
//  cannot use img (type [10][10]int) as type [][]int in return argument

go中对数组的使用过于死板,故常使用切片。

切片相当于数组的一个指针。和python中的数组类似

切片和底层的数组也是绑定的,切片的所有 *** 作都是在底层数组上,而不是切片上。

	s := []int{2, 3, 5, 7, 11, 13}
	printSlice(s) // len=6 cap=6 [2 3 5 7 11 13]

	// 截取切片使其长度为 0
	s = s[:0]
	printSlice(s)// len=0 cap=6 []

	// 拓展其长度
	s = s[:4]
	printSlice(s)// len=4 cap=6 [2 3 5 7]

	// 舍弃前两个值
	s = s[2:]
	printSlice(s)// len=2 cap=4 [5 7]
	var s []int
	printSlice(s)

	// 添加一个空切片
	s = append(s, 0)
	printSlice(s)

	// 这个切片会按需增长
	s = append(s, 1)
	printSlice(s)

	// 可以一次性添加多个元素
	s = append(s, 2, 3, 4)
	printSlice(s)

    // 将一
    s = append(s,b...)

二维切片的 *** 作

func Pic(dx, dy int) [][]uint8 {
	img := make([][]uint8,dy)
	for i  := range img{
		img[i] = make([]uint8,dx)
		for j  := range img[i]{
			img[i][j] = uint8(i*j)
		}
	}
	return img
}
映射

实现 WordCount。它应当返回一个映射,其中包含字符串 s 中每个“单词”的个数。函数 wc.Test 会对此函数执行一系列测试用例,并输出成功还是失败。

package main

import (
	"golang.org/x/tour/wc"
	"strings"
)
func WordCount(s string) map[string]int {
    m := make(map[string]int) 
	for _, w := range strings.Fields(s) {
		m[w] = m[w]+1
	}
	return m
}

func main() {
	wc.Test(WordCount)
}

https://blog.go-zh.org/go-slices-usage-and-internals

函数
package main

import "fmt"

func adder() func(int) int {
	sum := 0
	return func(x int) int {
		sum += x
		return sum
	}
}

func main() {
	pos, neg := adder(), adder()// 两个“对象"
	for i := 0; i < 10; i++ {
		fmt.Println(
			pos(i),
			neg(-2*i),
		)
	}
}
0 0
1 -2
3 -6
6 -12
10 -20
15 -30
21 -42
28 -56
36 -72
45 -90
并行 奇奇怪怪的语法
  1. 大括号

{ 不能单独一行

  1. 变量未使用

如果有变量未使用,则编译失败

package main
import (
   "fmt"
)
func main(){
   var x int = 10
   fmt.Println("hello")
   // _ = x 添加该行后可解决该问题 
}
// ** x declared but not used**

go中对该问题的解释时,有未使用的变量可能会有bug。 Can I stop these complaints about my unused variable/import?

但全局变量是可以声明后不使用的。

reference

https://tour.golang.org/welcome/1
https://www.runoob.com/go/go-tutorial.html

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4676156.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-07

发表评论

登录后才能评论

评论列表(0条)

保存