Go语言系列-Go基础语法(二)

四、 条件语句

相信大家或多或少的都知道一个if语句的大致格式,这里展示一下在Go语言中if语句的一个书写方式,如下所示:

/* 条件判断语句 */
func bounded(v int) int {
	// if条件里不需要使用括号
	if v > 50 {
		return 50
	} else if v < 0 {
		return 0
	} else {
		return v
	}
}

这样子就很有熟悉的感觉,下面以Go读取一个txt文档来展示一种不同的条件语句的写法(这里需要各位自行在各自对应目录下创建一个随意的txt文件即可),代码如下

/* 读取文件下正常条件语句*/
func readTxtFormat() {
	contents, err := os.ReadFile(filename)
	if err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s\n", contents)
	}
}

/* 读取文件下简化条件语句*/
func readTxtShorter() {
	if contents, err := os.ReadFile(filename); err != nil {
		fmt.Println(err)
	} else {
		fmt.Printf("%s\n", contents)
	}
}

虽然后一种写法略显简便,但是会存在一个问题,因为contents和err都是定义在if语句中,所以这两个变量的使用范围也仅限于条件语句中,而不能在语句外部进行操作,正如下图所示

在这里插入图片描述

此外,除了我们用的最多的if条件语句,我们也不能忘记还有switch语句,同样也是一种条件语句

让我们先看一下在GO语言中,switch语句的基本写法

/* switch语句 */
func eval(a, b int, op string) int {
	var result int
	switch op {
	case "+":
		// Go语言中,不需要额外书写break来停止
		result = a + b
	case "-":
		result = a - b
	case "*":
		result = a * b
	case "/":
		result = a / b
	default:
		// 添加报错,会中断程序的执行
		panic("unsupported operator" + op)
	}
	return result
}

当然,Go中switch还可以这么写,即在switch关键字后没有表达式,然后直接进入条件语句,如下

func grade(score int) string {
	grade := ""
	switch {
	case score < 0 || score > 100:
		panic(fmt.Sprintf("Wrong score: %d", score))
	case score < 60:
		grade = "F"
	case score < 70:
		grade = "D"
	case score < 80:
		grade = "C"
	case score < 90:
		grade = "B"
	case score <= 100:
		grade = "A"
	}
	return grade
}

五、 循环语句

上面说完了条件语句的两种形式,这里我们来说一下循环语句,在循环语句中,GO与其他语言基本上没有去区别,看下面一个示例

	sum := 0
	// for的条件不需要括号
	for i := 0; i < 100; i++ {
		sum += i
	}

这里,for循环的条件里,可以忽略起始条件,结束条件和递增表达式,我们看一个简单的例子(进制转换)

// 省略初始条件
func convertToBin(n int) string {
	result := ""
	for ; n > 0; n /= 2 {
		lsb := n % 2
		result = strconv.Itoa(lsb) + result
	}
	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 forever() {
	for {
		fmt.Println("aaa")
	}
}

与其他的语言不同的是,Go语言中没有While这种写法,但是上面三种省略,是不是会有一种While的熟悉感

六、 函数

说起函数,稍微有点基础的朋友们应该都不陌生,当然我们在上述的一些语法的讲解中,也都是使用了函数的形式,进行的书写

Go语言的函数与其他语言的函数书写形式不太一样,正如它自身变量的定义一样,它的形式为

func 函数名 (变量 类型, …) 返回值 { 函数体 }

这里的参数我们可以传入多个值,同时返回值也可以为多个值 ,具体形式如下所示

// 常见形式1,参数为a,b,op,返回值为int类型
func eval(a, b int, op string) int { 函数体}
// 常见形式2,参数为a,b,返回值定义为q,r,int类型
func div(a, b int) (q, r int) {函数体} 

上方的形式2,多个返回值的使用,我们一般只用于比较简单的函数方法,或者就是用来返回一些error,当然返回值的接收,可以由调用者自行定义,不必于函数定义的参数一致,例如:

// 函数为
func div(a, b int) (q, r int) {函数体} 

// 接收可以为
m, n = div(3, 4)
// 如果只想要其中某一个返回值,只需要让另外一个为_(下划线)即可
m, _ = div(3,4)

// 用于定义error
func eval(a ,b int, op string) (int error) {
		switch ... // (省略case部分,可以参考上方switch部分代码)
		default: 
			return 0, fmt.Errorf("unsupported operator: %s", + op)
}

上面便是Go语言函数的一个基本使用,但是,有些时候因为功能的原因,会导致整个函数看着很庞大,这里为了简化,Go语言还提供了复合函数的写法(函数式编程),代码如下:

func apply(op func(int, int) int, a, b int) int {
		return op(a, b)rr
}

// 方便理解,我这里贴出来完整函数,大家可以手写一下,看一下IDE的一个提示,并尝试运行一下
func apply(op func(int, int) int, a, b int) int {
	fmt.Printf("Calling %s with %d, %d\n", runtime.FuncForPC(reflect.ValueOf(op).Pointer()).Name(), a, b)
	return op(a, b)
}
func main() {
	// 定义匿名内部函数
	fmt.Println(apply(func(a int, b int) int {
		return int(math.Pow(float64(a), float64(b)))
	}, 3, 4))
}

这部分大家大致先看一下,后续还会有专门的文章来专门讲解一下函数式编程

七、 指针

指针,一说到我们就会想到C语言那个复杂的指针和指针的操作;很幸运,Go语言的指针没有那么复杂,相反,整个指针部分很好操作,我们先看一个简单的例子

func main() {
	var a int = 2 // 定义一个int类型的变量
	// *int  , int类型指针
	// &,用于取地址
	var pa *int // 定义一个整数类型的指针
	pa = &a // 把a的地址给pa
	*pa = 3 // 修改pa的引用值为3
	fmt.Println(a) // 3
}

Go语言指针,最大的特点就是不能进行预算,所以相比起来就会简单许多

但是一说到指针,我们就需要回顾两个概念:值传递,引用传递

  • 值传递:指在调用函数时,将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,就不会影响到实际参数
  • 引用传递:是指在调用函数时,将实际参数的地址传递到函数中,那么在函数中对参数进行修改,将会影响到实际参数

而Go语言只有值传递一种方式,即调用的时候,都会被复制一份,是不是听起来就很占用性能,所以我们来看一下,Go语言中,指针与参数之间的一个搭配,举一个比较简单的例子,交换两个数的值,大家可以先想一下结果,然后再写一下,看一下运行的结果

func swap1(a, b int) {
	a, b = b, a
}

func swap2(a, b *int) {
	*a, *b = *b, *a
}
func main() {
	a, b := 3, 4
	swap1(a, b)
	fmt.Println(a, b) // 3 4

	c, d := 3, 4
	swap2(&c, &d)
	fmt.Println(c, d) // 4 3
}

至此,Go语言的一个基本语法就告一段落了,后续将会进一步讲解一些Go语言的进阶使用方法,暂时还有问题的地方,不妨先往后进行学习,随着代码量的提升,一些目前不明白的地方也会逐渐理解,豁然开朗

本文至此便告一段落,祝各位码上无ERROR,键盘无BUG!!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值