Google资深工程师深度讲解Go语言-基础语法(二)「建议收藏」

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

二.内建变量类型

Google资深工程师深度讲解Go语言-基础语法(二)「建议收藏」Google资深工程师深度讲解Go语言-基础语法(二)「建议收藏」sGoogle资深工程师深度讲解Go语言-基础语法(二)「建议收藏」

  • 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
    }
    

     

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/111735.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • ubuntu18修改ssh端口(ssh 22端口拒绝)

    https://blog.csdn.net/md521/article/details/52597398

    2022年4月13日
    55
  • acwing-2983. 玩具(计算几何)

    acwing-2983. 玩具(计算几何)计算玩具收纳盒中,每个分区内的玩具数量。约翰的父母有一个烦恼—-约翰每次玩完玩具以后总会将玩具乱扔。他们为约翰准备了一个长方形的玩具收纳盒,用来放他的玩具。但是约翰非常调皮,每次都非常随意的将玩具扔进盒子中,使得所有玩具都随意混在一起,这让约翰难以找到他喜欢的玩具。对此,约翰的父母想出了一个对策,用若干个纸板将收纳盒分隔成若干个分区,这样至少扔到不同分区的玩具之间还是能分开的。下面是一个收纳盒的俯视图示例。1.jpg你的任务是,每当约翰将玩具扔进收纳盒中时,确定每个分区中有多少个玩具。输

    2022年8月9日
    2
  • 渗透测试流程包括_渗透测试包含哪些内容

    渗透测试流程包括_渗透测试包含哪些内容目录渗透测试步骤 步骤一:明确目标 步骤二:信息收集 步骤三:漏洞探索 步骤四:漏洞验证 步骤五:信息分析 步骤六:获取所需 步骤七:信息整理 步骤八:形成报告 #流程总结 面试补充说明渗透测试步骤渗透测试与入侵的区别:渗透测试:出于保护的目的,更全面的找出目标的安全隐患。入侵:不择手段的窃取或取得目标的最大权限并予以控制。(是具有破坏性的)步骤一:明确目标1、确定范围:规划测试目标的范围,以至于不会出现越界的情况。2、确定规则

    2025年6月15日
    0
  • batchnorm原理理解「建议收藏」

    batchnorm原理理解「建议收藏」接触CNN也一段时间了,最近也到了秋招期间,面试的时候可能会问到的一些内容需要做一个整理CNN-BN层参考了一个大神的博客,感觉讲的很深入也很好理解。我这里主要是对他的博客做一个自己的归纳整理,主要是为了方便自己去理解,也欢迎大家一起讨论自己的理解。这里给出大神的博客地址:https://blog.csdn.net/qq_25737169/article/details/79048…

    2022年5月16日
    42
  • USB接口定义

    USB接口定义USB接口标准USB是电脑的常见接口,有4根线,两根电源线和两个信号线,电源线正负极供电,接烦可能导致USB设备或电脑的南桥芯片烧坏。typeA即我们常见的标准USB大口,主流的可以分为USB2.0速度(几十M/S)和USB3.0速度(上百M/S),事实上目前有少量Type-A为USB3.110Gbps速度,常见于新的台式机主板上。typeB常见于打印机以及带触摸和U…

    2022年5月30日
    64
  • SSE的学习

    SSE的学习看到intel向量化指令在矩阵乘应用中的评估_softee的专栏-CSDN博客中描述的效果而心动,然后咨询了下博客园博主,我稍微看了下《simdforc++developers》感觉SSE这些指令更像一种寄存器语言,乍一接触略不适应。然而我的疑问是:1、如果对一个步骤我用了TBB/MKL/CILK这种易操作的并行指令,内部能否再用SSE指令,能否性能进一步提升?或者像OMP一样不适合嵌套并行?2、这种向量化指令是否只对无依赖性流程可用?对dst(i)=src(i)+dst(i-1);…

    2022年10月31日
    0

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号