Google资深工程师深度讲解Go语言-基础语法(二)

视频教程获取地址

一.变量的定义

1.使用var关键字

  • var a,b,c,bool
  • var s1,s2 string="hello","world"
  • 可放在函数内,或直接放在包内
  • 使用var()集中定义变量

2.让编译器自动决定类型

  • var a,b,i,s1,s2=true,false,3,"hello","world"

3.使用:=定义变量

  • a,b,i,s1,s2:=true,false,3,"hello","world"
  • 只能在函数内使用

测试用例代码

package main

import "fmt"

//函数外面定义变量时,必须使用var关键字,不能使用:=
//这些变量作用域,是包内变量,不存在全局变量说法
/*var aa=3
var ss  ="kkk"
var bb  = true*/
var (
	aa = 3
	ss = "kkk"
	bb = true
)

func variableZeroValue() {
	var a int
	var b string
	fmt.Printf("%d %q\n", a, b)
}

//定义变量类型,不能写在一行
func variableIntValue() {
	var a, b int = 3, 4
	var s string = "abc"
	println(a, b, s)
	//fmt.Printf("%d %d %q\n",a,b,s)
}

//省略变量类型,可以写在一行
func varTypeDefValue() {
	var a, b, c, s = 3, 4, true, "abc"
	println(a, b, c, s)
}

//省略var ,第一次定义使用:冒号来定义,第二次定义时使用等号
func variableValueShorter() {
	a, b, c, s := 3, 4, true, "abc"
	b = 5
	println(a, b, c, s)
}
func main() {
	fmt.Println("hello world 33")
	variableZeroValue()
	variableIntValue()
	varTypeDefValue()
	variableValueShorter()
	fmt.Println(aa,bb,ss)
}

结果

hello world 33
0 ""
3 4 abc
3 4 true abc
3 5 true abc
3 true kkk

二.内建变量类型

s

  • bool string
  • (u)int (u)int8 (u)int16,   (u)int32,(u)int64, uintptr 指针  加u无符号证书,不加u有符号整数,根据操作系统分,规定长度,不规定长度
  • byte rune 字符型,go语言的char类型,byte 8位,rune 32位
  • float32,float64,complex64,complex128 复数类型,complex64 的实部和虚部都是float32,complex128 实部和虚部都是float64

1.类型转换是强制的,没有隐士类型转换

package main

import (
	"fmt"
	"math"
	"math/cmplx"
)

func euler() {
	//c:=3+4i
	//fmt.Println(cmplx.Abs(c)) //5
	fmt.Printf("%.3f\n",
		cmplx.Exp(1i*math.Pi)+1) //(0.000+0.000i)

}

func triangle() {
	var a, b int = 3, 4
	var c int
	c = int(math.Sqrt(float64(a*a + b*b)))
	fmt.Println(c) //5 强制类型转换
}
func main() {
	euler()
	triangle()
}

2.变量定义要点:

  • 变量类型写在变量名之后
  • 编译器可推测变量类型
  • 没有char,只有rune
  • 原生支持复数类型
//常量
func consts() {
	//const filename = "abc.txt"
	//const a, b = 3, 4
	const(
	 filename = "abc.txt"
	 a, b = 3, 4
	 )
	var c int

	c = int(math.Sqrt(a*a + b*b))
	fmt.Print(filename, c)

}

//枚举
func enums(){
	/*const  (
		c=0
		java=1
		golang=2
		php=3
	)*/
	const  (
		c=iota  //iota 表示这组是自增值的
		_
		golang
		php
		javascript
	)
//b kb mb gb tb
	const (
		b= 1 <<(10*iota)
		kb
		mb
		gb
		tb
	)
	fmt.Println("\n")
	fmt.Println(c,javascript,golang,php)//0 4 2 3
	fmt.Println(b,kb,mb,gb,tb)//1 1024 1048576 1073741824 1099511627776
}

三.条件语句

if语句

  • if的条件里可以赋值
  • if的条件里赋值的变量作用域就在这个if语句里
const filename = "/Users/liutao/Desktop/vagrant/go/study/day0803/abc.txt"  //注意文件绝对路径
	if contents, err := ioutil.ReadFile(filename);err!=nil{
		fmt.Println(err)
	}else {
		fmt.Printf("%s\n", contents)
	}

 switch  panic作用:终端程序执行,并报错

  • switch会自动break,除非使用fallthrough
  • switch后可以没有表达式
func grade(score int) string {
	g := ""
	switch {
	case score < 0 || score > 100:
		panic(fmt.Sprintf("wrong score: %d", score))
	case score < 60:
		g = "F"
	case score < 80:
		g = "C"
	case score < 90:
		g = "B"
	case score <= 100:
		g = "A"
	default:
	}
	return g
}

//调用
func main() {
	fmt.Println(
	grade(0),
	grade(10),
	grade(59),
	grade(60),
	grade(89),
	grade(100),
	//grade(120), //panic 报错,中止执行
	//grade(-100),
	)
}

//执行结果
F F F C B A

四.循环

要点:

  1. for,if后面的条件没有括号
  2. if条件里也可以定义变量
  3. 没有while
  4. switch不需要break,也可以直接switch多个条件

for 语句

  • for的条件里不需要括号
  • for的条件里可以省略初始条件,结束条件,递增表达式
  • for省略初始条件,相当于while
  • for省略初始条件和递增条件,相当于while
  • for 初始条件,结束条件,递增表达式都不加就是死循环
package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

func fors() int {
	sum := 0
	for i := 1; i <= 100; i++ {
		sum += i
	}
	return sum
}

//1.省略初始条件,相当于while
func converToBin(n int) string {
	result := ""
	for ; n > 0; n /= 2 {
		lsb := n % 2
		result = strconv.Itoa(lsb) + result //Itoa 转换为字符串
	}
	return result
}

//2.省略初始条件和递增条件
func printile(filename string)  {
	file,err:=os.Open(filename)
	if err!=nil {
		panic(err)
	}
	scanner:=bufio.NewScanner(file)
	//省略初始条件和递增条件
	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}
}

//3.初始条件,结束条件,递增表达式都不加就是死循环 
func forever() string {
	for  {
		fmt.Println("abc")
	}
}

func main() {
	fmt.Println(fors())//5050

	fmt.Println(
		converToBin(5),//101
		converToBin(13),//1101
		converToBin(0),//空串
		)
	//forever()
	printile("/Users/liutao/Desktop/vagrant/go/study/day0803/abc.txt")
}

//执行结果
5050
101 1101 

/**下面文件内容**/
lxw
test
1234
hehh

五.函数

  • 函数返回多个值时,可以起名字
    ​​仅用于非常简单的函数
    对于调用者而言没有区别
    
    返回值类型写在后面(go 变量和返回值都是 名在前,类型在后)
    go可返回多个值,php只能返回一个值(字符串或数组,对象)
    函数作为参数(匿名函数)
    go没有默认参数和可选参数,但有可变参数列表
  • package main
    
    import (
    	"fmt"
    	"math"
    	"reflect"
    	"runtime"
    )
    
    func eval(a, b int, op string) (int, error) {
    	switch op {
    	case "+":
    		return a + b, nil
    	case "-":
    		return a - b, nil
    	case "*":
    		return a * b, nil
    	case "/":
    		//return a / b
    		q, _ := div(a, b)
    		return q, nil
    	default:
    		//panic("unsupported operation:" + op)  //终端执行
    		return 0, fmt.Errorf("unsupported operation: %s", op) //不中断,0 unsupported operation: X
    	}
    }
    
    //多返回值
    func div(a, b int) (q, r int) {
    	return a / b, a % b
    
    }
    
    func apply(op func(int, int) int, a, b int) int {
    	p := reflect.ValueOf(op).Pointer()
    	opName := runtime.FuncForPC(p).Name()
    	fmt.Printf("calling function %s with args"+"(%d,%d)\n", opName, a, b)
    	return op(a, b)
    }
    
    func pow(a, b int) int {
    	return int(math.Pow(float64(a), float64(b)))
    }
    
    //可变参数列表
    func sum(nubers ...int)int{
    	s:=0
    	for i:=range nubers{
    		s+=nubers[i]
    	}
    	return s
    }
    func main() {
    	//fmt.Println(eval(13, 4, "X"))
    	if result, err := eval(13, 4, "X"); err != nil {
    		fmt.Println("error:", err) //error: unsupported operation: X
    	} else {
    		fmt.Println(result)
    	}
    
    	q, r := div(13, 3)
    	fmt.Println(q, r)
    
    	//fmt.Println(apply(pow, 3, 4))
    
    	fmt.Println(apply(
    		func(a int, b int) int {
    			return int(math.Pow(
    				float64(a), float64(b)))
    		}, 3, 4))
    
    	fmt.Println(sum(1,2,3,4,5)) //15
    }

    六.指针

  • 指针不能运算

  •  go语言只有值传递一种方式

    package main
    
    import "fmt"
    
    //go 语言只有值传递一种方式
    //交换a,b 的值 * 指针类型
    
    //方法一
    /*func swap(a,b *int){
    	*b,*a=*a,*b
    }*/
    
    //方法二
    func swap(a,b int)(int,int)  {
    	return b,a
    }
    func main() {
    	a,b:=3,4
    
    	//方法一
    	//swap(&a,&b)
    	
    	//方法二
    	a,b=swap(a,b)
    	fmt.Println(a,b) //4,3
    }
    

     

posted @ 2020-08-03 20:00  码农编程进阶笔记  阅读(60)  评论(0编辑  收藏  举报
返回顶部 有事您Q我