go语言基础知识学习第一天

终端中运行命令

go run hello.go

标识符

由字母、数字和下划线组成

关键字 25个
break default func interface select case defer go map struct chan else goto
package switch const fallthrough range type continue for import return var

常见关键字解释
1.select

package main

import "fmt"

func main() {
   var c1, c2, c3 chan int
   var i1, i2 int
   select {
   	  // 每个 case 都必须是一个通信
      case i1 = <-c1:
         fmt.Printf("received ", i1, " from c1\n")
      case c2 <- i2:
         fmt.Printf("sent ", i2, " to c2\n")
      case i3, ok := (<-c3):  // same as: i3, ok := <-c3
         if ok {
            fmt.Printf("received ", i3, " from c3\n")
         } else {
            fmt.Printf("c3 is closed\n")
         }
      // 默认执行
      default:
         fmt.Printf("no communication\n")
   }    
}

2.defer
可以将一个方法延迟到包裹该方法的方法返回时执行
可以用来处理关闭文件句柄等收尾操作
defer触发时机

  • 包裹defer的函数返回时
  • 包裹defer的函数执行到末尾时
  • 所在的goroutine发生panic时
package main

import "fmt"

// 当一个方法中有多个defer时
// defer会将要延迟执行的方法“压栈”
// 当defer被触发时,将所有“压栈”的方法“出栈”并执行
func stackingDefers()  {
	defer func() {
		fmt.Printf("1")
	}()
	defer func() {
		fmt.Printf("2")
	}()
	defer func() {
		fmt.Printf("3")
	}()
}

func main()  {
	stackingDefers()	// 执行结果为 321
}

// 匿名返回值
func returnValues() int {
	var result int
	defer func() {
		// 返回刚才创建的返回值(retValue)
		result++
		fmt.Println("defer")
	}()
	// 将result赋值给返回值 可以理解成Go自动创建了一个返回值retValue,相当于执行retValue = result
	// 检查是否有defer,如果有则执行
	return result
}

// 命名返回值
func namedReturnValues() (result int) {
	// return和defer是“同时”执行的
	defer func() {
		result++
		fmt.Println("defer")
	}()
	// 由于返回值在方法定义时已经被定义,所以没有创建retValue的过程
	// result就是retValue,defer对于result的修改也会被直接返回
	return result
}

func main()  {

	r := returnValues()
	fmt.Println(r)	// 0

	k := namedReturnValues()
	fmt.Println(k)	// 1
}

循环中定义defer可能导致大量的资源开销

判断执行没有err之后,再defer释放资源

resp, err := http.Get(url)
// 先判断操作是否成功
if err != nil {
    return err
}
// 如果操作成功,再进行Close操作
defer resp.Body.Close()

调用os.Exit时defer不会被执行

func deferExit() {
    defer func() {
        fmt.Println("defer")
    }()
    os.Exit(0)
}

3.chan

  • 如果说 goroutine 是 Go语言程序的并发体的话
  • 那么 channels 就是它们之间的通信机制
  • 通道像一个传送带或者队列,总是遵循先入先出(First In First Out)的规则,保证收发数据的顺序
  • 通道是引用类型,需要使用 make 进行创建 ch1 := make(chan int)
    在这里插入图片描述
package main

import (
	"fmt"
	"time"
)

func testChan() {
	// 构建一个通道
	ch := make(chan int)
	// 开启一个并发匿名函数
	go func() {
		fmt.Println("start goroutine")
		// 通过通道通知main的goroutine
		ch <- 0
		fmt.Println("exit goroutine")
	}()
	fmt.Println("wait goroutine")
	// 等待匿名goroutine
	<-ch
	fmt.Println("all done")
}

func main() {
	testChan()
	// 构建一个通道
	ch := make(chan int)
	// 开启一个并发匿名函数
	go func() {
		// 从3循环到0
		for i := 3; i >= 0; i-- {
			// 发送3到0之间的数值
			ch <- i
			// 每次发送完时等待
			time.Sleep(time.Second)
		}
	}()
	// 遍历接收通道数据
	for data := range ch {
		// 打印通道数据
		fmt.Println(data)
		// 当遇到数据0时, 退出接收循环
		if data == 0 {
			break
		}
	}
}

// 运行结果为 3 2 1 0

4.goto通过标签进行代码间的无条件跳转

package main

import "fmt"

func main() {
	for x := 0; x < 10; x++ {
		for y := 0; y < 10; y++ {
			if y == 2 {
				// 跳转到标签
				goto breakHere
			}
		}
	}
	// 手动返回, 避免执行进入标签
	return

	// 标签
	breakHere:
		fmt.Println("done")	// 输出 done
}

5.switch
Go语言的 switch 要比C语言的更加通用
表达式不需要为常量,甚至不需要为整数
case 按照从上到下的顺序进行求值,直到找到匹配的项

package main

import "fmt"

func main()  {
	var a = "hello"
	switch a {
	case "hello":
		fmt.Println(1)
	case "world":
		fmt.Println(2)
	default:
		fmt.Println(0)
	}
}
预定义标识符 36个
append bool byte cap close complex complex64 complex128 uint16
copy false float32 float64 imag int int8 int8 int16 uint32 int32
int64 iota len make new nil panic uint64 print println real recover
string true uint uint8 uintptr
变量声明

var age int;

Go语言数据类型
布尔型
	true 或者 false
	var b bool = true
数字类型
	int float32 float64
	uint8 无符号8位整型
	uintptr
	complex64 complex128
字符串类型
	一串固定长度的字符连接起来的字符序列
派生类型
	指针类型 Pointer
	数组类型
	结构化类型 struct
	Channel 类型
	函数类型
	切片类型
	接口类型 interface
	Map类型
变量声明

如果没有初始化则变量默认为零值
数值类型(包括complex64/128)为 0
布尔类型为 false
字符串为 “”(空字符串)
以下几种类型为 nil

:= 声明新的变量

iota 特殊常量 可以被认为是一个被编译器修改的常量

运算符

算术运算符 + - * / % ++ --
逻辑运算符 &&(and) ||(or) !(not)
位运算符 & | ^ <<(乘以2的n次方) >>(除以2的n次方)
*(指针变量)&(返回变量存储地址)

运算符优先级
优先级5 * / % << >> & &^
优先级4 + - | ^
优先级3 == != < <= > >=
优先级2 &&
优先级1 ||

指针
  • 一个指针变量指向了一个值的内存地址
  • 当一个指针被定义后没有分配到任何变量时值为 nil
数组和结构体
  • 数组可以存储同一类型的数据
  • 但在结构体中我们可以为不同项定义不同的数据类型
切片

cap()可以测量切片最长可以达到多少
range 关键字用于 for 循环中

  • 迭代数组(array)
  • 切片(slice)
  • 通道(channel)
  • 集合(map)的元素

go 语言代码
package main

import (
	"WorldProject/stringutil"
	"fmt"
)

func main()  {
	// 这是我的第一个程序将结果输出到控制台
	/*
	这是多行注释的写法
	这是多行注释的写法
	这是多行注释的写法
	*/
	fmt.Printf(stringutil.Reverse("Hello World"))
	var a *int
	var b []int
	var c map[string] int
	var d chan int
	var e func(string) int
	var f error
	fmt.Printf("%v %v %v %v %v %v", a, b, c, d, e, f)
	const (
		a1 = iota
		b1
		c1
		d1 = "solomon"
		e1
		f1 = 100
		g1
		h1 = iota
		i1
	)
	fmt.Println(a1, b1, c1, d1, e1, f1, g1, h1, i1)

	const (
		a2 = 1 << iota
		b2 = 3 << iota
		c2
		d2
	)
	fmt.Println("a2 = ", a2)
	fmt.Println("b2 = ", b2)
	fmt.Println("c2 = ", c2)
	fmt.Println("d2 = ", d2)

	var a3 int=20
	var ip *int
	ip = &a3
	fmt.Printf("a3变量的地址是:%x\n", &a3)
	fmt.Printf("ip变量储存的指针地址是:%x\n", ip)
	fmt.Printf("ip变量的值是:%x\n", *ip)

	type Books struct {
		title string
		author string
		subject string
		bookID int
	}
	fmt.Println(Books{"Go 语言", "www.go.org", "Go 语言教程", 6495407})

	var number = make([]int, 3, 5)
	printSlice(number)

	nums := []int{2, 3, 4}
	sum := 0
	for _, num := range nums {
		sum += num
	}
	fmt.Println("sum = ", sum)
	for i, num := range nums {
		if num == 3 {
			fmt.Println("index = ", i)
		}
	}
	strs := map[string]string{"a": "apple", "c": "banana"}
	for k, v := range strs {
		fmt.Printf("%s -> %s\n", k, v)
	}
	for i, c := range "go" {
		fmt.Println(i, c)
	}
}

func printSlice(x []int) {
	fmt.Printf("len=%d cap=%d slice=%v\n", len(x), cap(x), x)
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值