Go语言基础语法(一)

目录

1.变量的定义

1.1当使用var关键字的时候

1.2可以让编译器自动决定类型

1.3使用:=定义变量

2.内建变量类型

2.1complex类型

2.2强制类型转换

3.常量与枚举

3.1常量

3.2枚举

4.条件语句

4.1if

4.2switch

5.循环

6.函数

7.指针


1.变量的定义

1.1当使用var关键字的时候

var a,b,c bool

var s1,s2 string ="hello world"

可以放在函数内,或者直接放在包内

可以使用var()集中定义变量

1.2可以让编译器自动决定类型

var a,b,i,s1,s2=true,false,3,“hello”,“world”

1.3使用:=定义变量

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

只能在函数内使用

2.内建变量类型

bool,string

(u)int,(u)int8,(u)int16,(u)int32,(int)64,uintptr(加上“u”就是无符号整数,不加就是有符号整数,后面的数字是规定长度,不规定长度是根据系统来,系统多少位就占多少位,最后一个是指针)

byte,rune(byte是8位的,rune是go语言的字符类型,32位,相当于别的语言的“char”)

float32,float64,complex64,complex128(complex是指复数,complex64的实虚部是32位的float,complex128的实虚部是64位的float)

2.1complex类型

c := 3 + 4i
fmt.Println(cmplx.Abs(c))

结果是5

2.2强制类型转换

go语言只有强制类型转换

例如:求直角边为3,4的三角形的斜边长,只能这样写:

var a, b int = 3, 4
var c int
c = int(math.Sqrt(float64(a*a + b*b)))
fmt.Println(c)

3.常量与枚举

3.1常量

func consts() {
	const filename = "abc.txt"
	const a, b = 3, 4
	var c int
	c = int(math.Sqrt(a*a + b*b))
	fmt.Println(filename, c)
}

常量是指定义后不能修改的量,定义常量的时候可以和自变量定义一样在后面加上类型,也可以不加。

但是当不加类型的时候,就比较有意思了,它的类型是不确定的,当你在用它的时候需要它是什么类型它就是什么类型,如上面的代码中math.Sqrt()需要传入float类型,此时它就是float类型的。

也可以使用括号来定义

func consts() {
	const (
		filename = "abc.txt"
		a, b     = 3, 4
	)

	var c int
	c = int(math.Sqrt(a*a + b*b))
	fmt.Println(filename, c)
}

3.2枚举

func enums() {
	const (
		cpp    = 0
		java   = 1
		python = 2
		golang = 3
	)
	fmt.Println(cpp, java, python, golang)
}

go语言里面用常量定义枚举类型,如上,结果为0123

但是go里面提供了一种自增值实现,如下,结果依然为0123

func enums() {
	const (
		cpp = iota
		java
		python
		golang
	)
	fmt.Println(cpp, java, python, golang)
}

还可以作为种子来定义枚举类型,如下。

func enums() {
	const (
		cpp = iota
		_
		python
		golang
		javascrip
	)
	//b,kb,mb,gb,tb,pb
	const (
		b = 1 << (10 * iota)//左移0位
		kb//左移10位
		mb//左移20位
		gb//左移30位
		tb//左移40位
		pb//左移50位
	)
	fmt.Println(cpp, javascrip, python, golang)
	fmt.Println(b, kb, mb, gb, tb, pb)
}

//结果为:
//0 4 2 3
//1 1024 1048576 1073741824 1099511627776 1125899906842624

到这里为止,以上第一部分内容所有demo的整个代码如下:

package main

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

var (
	aa = 3
	ss = "kkk"
	bb = true
)

func variableZeroValue() {
	var a int
	var s string
	fmt.Printf("%d %q\n", a, s)
}
func variableInitialValue() {
	var a, b int = 3, 4
	var s string = "abc"
	fmt.Println(a, b, s)
}

func variableTypeDeduction() {
	var a, b, c, s = 3, 4, true, "def"
	fmt.Println(a, b, c, s)
}

func variableShorter() {
	a, b, c, s := 3, 4, true, "def"
	b = 5
	fmt.Println(a, b, c, s)
}

func euler() {
	fmt.Printf("%.3f\n", cmplx.Exp(1i*math.Pi)+1)

}

func triangle() {
	var a, b int = 3, 4
	var c int
	c = int(math.Sqrt(float64(a*a + b*b)))
	fmt.Println(c)
}

func consts() {
	const (
		filename = "abc.txt"
		a, b     = 3, 4
	)

	var c int
	c = int(math.Sqrt(a*a + b*b))
	fmt.Println(filename, c)
}

func enums() {
	const (
		cpp = iota
		_
		python
		golang
		javascrip
	)
	//b,kb,mb,gb,tb,pb
	const (
		b = 1 << (10 * iota)
		kb
		mb
		gb
		tb
		pb
	)
	fmt.Println(cpp, javascrip, python, golang)
	fmt.Println(b, kb, mb, gb, tb, pb)
}

func main() {
	fmt.Println("hello world") //打印语句
	variableZeroValue()        //不赋值的变量声明方式
	variableInitialValue()     //赋值的变量声明方式
	variableTypeDeduction()    //不带类型的变量声明方式
	variableShorter()          //用冒号定义变量,但只能在函数内使用
	fmt.Println(aa, ss, bb)    //打印包内变量
	euler()                    //实现欧拉公式
	triangle()                 //强制类型转换举例
	consts()                   //常量举例
	enums()                    //枚举类型举例
}

4.条件语句

4.1if

写一个读文件的demo,如下。

func main() {
	const filename = "abc.txt"
	centents, err := ioutil.ReadFile(filename)//第一个参数是文件内容,第二个参数是报错信息
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s\n", centents)
	}

}

go语言可以把if写成这样:

func main() {
	const filename = "abc.txt"
	if contents, err := ioutil.ReadFile(filename); err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s\n", contents)
	}

}

但是这种写法,centents是不能在if模块外面用了,也就是作用域仅在if里面。

4.2switch

写一个demo如下。

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"
	}
	return g

}

注意:switch后面可以跟一个符号,例如score。但是也可以不跟。每个case最后不用写break,默认每个case后面都有一个break,如果希望没有break,那就加上一个fallthrough。

5.循环

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

//结果是4950

for的条件里不需要括号的。

for的条件里可以省略初始条件,结束条件,递增表达式。

下面是一个十进制转二进制的demo:

func convertToBin(n int) string {
	result := ""
	for ; n > 0; n /= 2 {
		lsb := n % 2
		result = strconv.Itoa(lsb) + result //lsb要转成字符串
	}
	return result
}

//这里的初始条件是省略的

下面是逐行读取文件内容的demo:

func printFile(filename string) {
	file, err := os.Open(filename)
	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}

}

//这里省略了初始条件和递增条件

下面是省略初始条件,结束条件,递增条件的demo:

func forver() {
	for {
		fmt.Println("毛同学")
	}
}


//这里省略了起始条件,终止条件,递增条件。

go语言里面没有while

到这里为止,以上第二部分内容所有demo的整个代码如下:

package main

import (
	"fmt"
	"io/ioutil"
)

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"
	}
	return g

}
func main() {
	const filename = "abc.txt"
	if contents, err := ioutil.ReadFile(filename); err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s\n", contents)
	}
	fmt.Println(
		grade(0),
		grade(59),
		grade(60),
		grade(82),
		grade(99),
		grade(100),
		grade(101),
	)
}


package main

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

func forDemo() {
	sum := 0
	for i := 0; i < +100; i++ {
		sum += i
	}
	fmt.Println(sum)
}
func convertToBin(n int) string {
	result := ""
	for ; n > 0; n /= 2 {
		lsb := n % 2
		result = strconv.Itoa(lsb) + result //lsb要转成字符串
	}
	return result
}

func printFile(filename string) {
	file, err := os.Open(filename)
	if err != nil {
		panic(err)
	}

	scanner := bufio.NewScanner(file)

	for scanner.Scan() {
		fmt.Println(scanner.Text())
	}

}

func forver() {
	for {
		fmt.Println("毛同学")
	}
}

func main() {
	forDemo()
	fmt.Println(
		convertToBin(5),  //101
		convertToBin(13), //1101
		convertToBin(72387885),
	)

	printFile("abc.txt")
	forver()
}

6.函数

一般定义的形式为:

func eval(a,b int op string) int

以下是返回一个值的简易计算器demo:

func eval(a, b int, op string) int {
	switch op {
	case "+":
		return a + b
	case "-":
		return a - b
	case "*":
		return a * b
	case "/":
		return a / b

	default:
		panic("unsupported operation:" + op)
	}
}

以下是两个返回值的函数,为带余数的除法的实现demo:

func div(a, b int) (int, int) {
	return a / b, a % b

}

还可以给返回值定义:

func div(a, b int) (q, r int) {
	q = a / b
	r = a % b
	return

}

x, y := div(10, 3)//用x和y来接收这两个返回值
fmt.Println(x, y)

//与上面的值一样的结果

当函数有两个返回值,但是只想用其中一个返回值的时候:

func div(a, b int) (q, r int) {
	q = a / b
	r = a % b
	return

}

x, _ := div(10, 3)//用x和y来接收这两个返回值
fmt.Println(x)

//与上面的值一样的结果

用“_”就可以了

go语言是一种函数式编程语言,用函数式编程修改建议计算器代码,如下:

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)
}
//这里参数有3个,第一个是函数op,然后是a,b


fmt.Println(apply(func(a int, b int) int {
		return int(math.Pow(float64(a), float64(b)))
	}, 3, 4))

//这里首先传入了一个匿名函数,然后传入了3和4

go语言没有c++的那种什么重载啊之类的复杂的语法,但是有可变参数列表:

func sum(numbers ...int) int {
	s := 0
	for i := range numbers {
		s += numbers[i]
	}
	return s
}

//这里的...int的意思就是无论你传入多少个参数都可以


fmt.Println(sum(1, 2, 3, 4, 5))

到这里为止,以上第三部分内容所有demo的整个代码如下:

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, nil

	default:
		return 0, fmt.Errorf("unsupported operation:%s", op)

	}
}
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 div(a, b int) (q, r int) {
	q = a / b
	r = a % b
	return

}

func sum(numbers ...int) int {
	s := 0
	for i := range numbers {
		s += numbers[i]
	}
	return s
}

func main() {

	fmt.Println(eval(3, 4, "*"))
	x, y := div(10, 3)
	fmt.Println(x, y)
	if result, err := eval(3, 4, "x"); err != nil {
		fmt.Println("Error:", err)
	} else {
		fmt.Println(result)
	}

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

7.指针

和c语言不同,go语言的指针相对简单,简单在go语言的指针不能运算。

var a int =2  //定义了变量a,赋值为2
var pa *int=&a //定义了一个指针,指向了a
*pa=3
fmt.Println(a)

//这里打印结果为3

那么,go语言的函数是值传递还是引用传递?

在c++中如下代码:

void pass_by_val(int a){
    a++;
}

void pass_by_ref(int& a){
    a++;
}




int main(){
    int a =3;
pass_by_val(a);
printf("After pass_by_val:%d\n",a);


pass_by_ref(a);
printf("After pass_by_ref:%d\n",a);

}

//结果应该是3,4

值传递是把传入的值拷贝了一份给函数,本身是不受函数内影响的,类似于“借你用”。

引用传递是指把地址“告诉”了函数,这个函数是与变量共享的,类似于“一起用”。

上面这个demo是c++,它可以值传递也可以引用传递,java,python大多都是引用传递。

Go语言只有值传递一种方式。

那么当交换两个参数值,可以这样实现:

func swap(a, b int) (int, int) {
	return b, a
}


a, b := 3, 4
a, b = swap(a, b)
fmt.Println(a, b)

Go语言基础语法(一)

Go语言基础语法(二)

于2021年11月9日整理

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值