go(二)语法学习笔记

函数

1.函数可以没有参数或接受多个参数。
2.当连续两个或多个函数的已命名形参类型相同时,除最后一个类型以外,其它都可以省略。

在本例中,add 接受两个 int 类型的参数。

注意类型在变量名 之后。

package main

import "fmt"

func add(x int, y int) int {
	return x + y
}
//或者
func add2(x,y int) int{
   return x+y
}
func main() {
	fmt.Println(add(3, 4))
		fmt.Println(add2(3, 4))
}
7
7

多值返回

swap
//多值返回

func swap (x,y string ) (string,string){
	return  y,x
}
func main()  {
	fmt.Println(swap("hello","world"))
}
world hello

Go 的返回值可被命名,它们会被视作定义在函数顶部的变量。

返回值的名称应当具有一定的意义,它可以作为文档使用。

没有参数的 return 语句返回已命名的返回值。也就是 直接 返回。

直接返回语句应当仅用在下面这样的短函数中。在长的函数中它们会影响代码的可读性。

func add2(x,y int) (sum,diff int){
	return x+y , x-y
}//仅用在下面这样的短函数中。在长的函数中它们会影响代码的可读性
func add2(x,y int) (sum,diff int){
	 sum =x+y 
	 diff =x-y
	 return
}
func main()  {
	fmt.Println(add2(3,4))
}

变量

var 语句用于声明一个变量列表,跟函数的参数列表一样,类型在最后。

就像在这个例子中看到的一样,var 语句可以出现在包或函数级别。

var a,b,c,d bool

func main()  {
	var a = true
	fmt.Println(a,b,c,d)
}
true false false false

变量的初始化

变量声明可以包含初始值,每个变量对应一个。

如果初始化值已存在,则可以省略类型;变量会从初始值中获得类型。

var a,b,c,d int = 1,2,3,4
func main()  {
	var e = true  //初始化值已存在,省略类型,变量从初始值中获得类型,true是bool型,直接定义e为bool
	fmt.Println(a,b,c,d,e)
}
1 2 3 4 true  

短变量声明

在函数中,简洁赋值语句 := 可在类型明确的地方代替 var 声明。

函数外的每个语句都必须以关键字开始(var, func 等等),因此 := 结构不能在函数外使用。

func add2(x,y int) (sum,diff int){
	z:=3 //:= 结构不能在函数外使用
	sum=x+y
	diff=x-y+z
	return
}

Go 的基本类型有

bool

string

int  int8  int16  int32  int64
uint uint8 uint16 uint32 uint64 uintptr

byte // uint8 的别名

rune // int32 的别名
    // 表示一个 Unicode 码点

float32 float64

complex64 complex128

本例展示了几种类型的变量。 同导入语句一样,变量声明也可以“分组”成一个语法块。

int, uint 和 uintptr 在 32 位系统上通常为 32 位宽,在 64 位系统上则为 64 位宽。 当你需要一个整数值时应使用 int 类型,除非你有特殊的理由使用固定大小或无符号的整数类型。

package main

import (
	"fmt"
	"math/cmplx"
)

var (
	ToBe   bool       = false
	MaxInt uint64     = 1<<64 - 1
	z      complex128 = cmplx.Sqrt(-5 + 12i)
	s float32 = 2.1
	n float64 =3.3
	t byte =33
	m rune =32
)

func main() {
	fmt.Printf("Type: %T Value: %v\n", ToBe, ToBe)
	fmt.Printf("Type: %T Value: %v\n", MaxInt, MaxInt)
	fmt.Printf("Type: %T Value: %v\n", z, z)
}

零值

没有明确初始值的变量声明会被赋予它们的 零值。


零值是:

数值类型为 0,
布尔类型为 false,
字符串为 ""(空字符串)。
0 0 false ""

类型显式转换

Go 在不同类型的项之间赋值时需要显式转换。 例子中 float64 或 uint 和之前的类型不一致 必须声明类型

package main

import (
	"fmt"
	"math"
)

func main() {
	var x, y int = 3, 4
	var f float64 = math.Sqrt(float64(x*x + y*y))
	var z uint = uint(f)
	fmt.Println(x, y, z)
}

类型推导

在声明一个变量而不指定其类型时(即使用不带类型的 := 语法或 var = 表达式语法),变量的类型由右值推导得出。

当右值声明了类型时,新变量的类型与其相同:

var i int
j := i // j 也是一个 int

不过当右边包含未指明类型的数值常量时,新变量的类型就可能是 int, float64 或 complex128 了,这取决于常量的精度:

i := 42           // int
f := 3.142        // float64
g := 0.867 + 0.5i // complex128

尝试修改示例代码中 v 的初始值,并观察它是如何影响类型的。

package main

import "fmt"

func main() {
	v := "jjj"// 修改这里!
	fmt.Printf("v is of type %T\n", v)
}

常量

常量的声明与变量类似,只不过是使用 const 关键字。

常量可以是字符、字符串、布尔值或数值。

常量不能用 := 语法声明。

package main

import "fmt"

const Pi = 3.14

func main() {
	const World = "世界"
	fmt.Println("Hello", World)
	fmt.Println("Happy", Pi, "Day")

	const Truth = true
	fmt.Println("Go rules?", Truth)
}

循环

go只有一种循环 for

组成:

 for 初始化;条件表达式;后置语句{
       循环体
 }

一旦条件表达式的布尔值为 false,循环迭代就会终止。

注意:和 C、Java、JavaScript 之类的语言不同,Go 的 for 语句后面的三个构成部分外没有小括号, 大括号 { } 则是必须的。

package main

import "fmt"

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

初始化语句和后置语句是可省略。

go中的while
package main

import "fmt"

func main() {
	sum := 1
	for sum < 1000 {
		sum += sum
	}
	fmt.Println(sum)
}
无限循环

如果省略循环条件,该循环就不会结束,因此无限循环可以写得很紧凑

func main() {
	for {
	}
}
没有条件的 switch

没有条件的 switch 同 switch true 一样。

这种形式能将一长串 if-then-else 写得更加清晰。

switch  {
	case today>"2019-01-01 00:00:00":
		fmt.Print("ssss")
	case today<"2020-02-02":
		fmt.Print("dssds")
	default:
		fmt.Print("default")
	}
defer

defer 语句会将函数推迟到外层函数返回之后执行。

推迟调用的函数其参数会立即求值,但直到外层函数返回前该函数都不会被调用。

defer fmt.Println("word")
	fmt.Println("hello")

print、printf、printIn区别:
https://blog.csdn.net/geniushorse/article/details/53490148

defer 栈

推迟的函数调用会被压入一个栈中。当外层函数返回时,被推迟的函数会按照后进先出的顺序调用。

func defers(){
	fmt.Println("begin")
	for  i:=0;i<10;i++{
		defer fmt.Println(i)
	}
	fmt.Println("end")
}
begin
end
9
8
7
6
5
4
3
2
1
0
指针

Go 拥有指针。指针保存了值的内存地址。
类型 * T是指向T类型的指针 。其零值为 nil。

var p *int

&操作符会生成
有点难,一会再补

slice和array
概念:

数组:类型[n]T 表示拥有n个T类型的值的数组
切片:类型[]T 表示一个元素为T类型的切片

表达式:

数组:var a [10]int 声明变量a为10个整数的数组
切片:a[low:high] low:下界 high:上界 区间为半闭半开
以下表达式创建了一个切片,它包含 a 中下标从 1 到 3 的元素:a[1:4]

长度:

数组:长度是类型的一部分,不可变
切片:为数组元素提供动态大小的、灵活的视角。在实践中,切片比数组更常用
切片的长度就是它所包含的元素个数。
切片的容量是从它的第一个元素开始数,到其底层数组元素末尾的个数。
切片 s 的长度和容量可通过表达式 len(s) 和 cap(s) 来获取。

举例:

数组:

name := [4]string{
		"a","b","c","d",
	}
 [3]bool{true, true, false}
切片(初始化):
name := []string{
		"a","b","c","d",
	}
[]bool{true, true, false}
s := []struct {
		i int
		b bool
	}{
		{2, true},
		{3, false},
		{5, true},
		{7, true},
		{11, false},
		{13, true},
	}
用 make 创建切片

make 函数会分配一个元素为零值的数组并返回一个引用了它的切片:

var slice1 []type = make([]type, len)
也可以简写为
slice1 := make([]type, len)

a := make([]int, 5)  // len(a)=5

要指定它的容量,需向 make 传入第三个参数:

make([]T, length, capacity) //这里 len 是数组的长度并且也是切片的初始长度
b := make([]int, 0, 5) // len(b)=0, cap(b)=5
b = b[:cap(b)] // len(b)=5, cap(b)=5
b = b[1:]      // len(b)=4, cap(b)=4

这里 len 是数组的长度并且也是切片的初始长度

append
func append(s []T, vs ...T) []T

append 的第一个参数 s 是一个元素类型为 T 的切片,其余类型为 T 的值将会追加到该切片的末尾。

append 的结果是一个包含原切片所有元素加上新添加元素的切片。

当 s 的底层数组太小,不足以容纳所有给定的值时,它就会分配一个更大的数组。返回的切片会指向这个新分配的数组。

var numbers[]int
numbers=append(numbers,2,3,4)
//这里需要赋值给追加数组的名字,不然会报错
copy
var numbers[]int
copy (numbers1,numbers)
nil
func main() {
   var numbers []int

   fmt.Printf("len=%d cap=%d slice=%v\n",len(numbers ),cap(numbers ),numbers )

   if(numbers == nil){
      fmt.Printf("切片是空的")
   }
}
range

for 循环的 range 形式可遍历切片或映射。
可以将下标或值赋予 _ 来忽略它。

for i, _ := range pow
for _, value := range pow
若你只需要索引,忽略第二个变量即可。

for i := range pow

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值