Go语言基础(七)—— Go语言for循环语句、Go字符串、Go语言函数

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/The_Reader/article/details/84146913

for循环

Go语言的For循环有3种形式,只有其中的一种使用分号,和C语言种的for一样:

for init; condition; post { }

和C语言种while一样:

for condition { }

说明:

  1. init: 一般为赋值表达式,给控制变量赋初值;
  2. condition: 关系表达式或逻辑表达式,循环控制条件;
  3. post: 一般为赋值表达式,给控制变量增量或减量。

for 语句执行过程如下:
①先对表达式 1 赋初值;
②判别赋值表达式 init 是否满足给定条件,若其值为真,满足循环条件,则执行循环体内
语句,然后执行 post,进入第二次循环,再判别 condition;否则判断 condition 的值为假,
不满足条件,就终止 for 循环,执行循环体外语句。
for 循环的 range 格式可以对 slice、map、数组、字符串等进行迭代循环。格式如下:

for key, value := range oldMap {
newMap[key] = value
}

For循环的嵌套:

for [condition | ( init; condition; increment ) | Range]
{
for [condition | ( init; condition; increment ) | Range]
{
statement(s);
}
statement(s);
}

循环控制语句

循环控制语句可以控制循环体内语句的执行过程。GO 语言支持以下几种循环控制语句:

  • break语句:经常用于终端当前for循环或跳出switch语句
  • continue语句:跳过当前循环的剩余语句,然后继续进行下一轮循环。
  • goto语句 :将控制转移到被标记的语句

break语句:跳出循环

Go 语言中 break 语句用于以下两方面:
1. 用于循环语句中跳出循环,并开始执行循环之后的语句。

2. break 在 switch(开关语句)中在执行一条 case 后跳出语句的作用。
continue语句

Go 语言的 continue 语句 有点像 break 语句。但是 continue 不是跳出循环,而是跳过当前循环执行下一次循环语句。for 循环中,执行 continue 语句会触发 for 增量语句的执行。
goto

Go 语言的 goto 语句可以无条件地转移到过程中指定的行。goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。
无限循环

如果循环中条件语句永远不为 false 则会进行无限循环,我们可以通过 for 循环语句中只设置一个条件表达式来执行无限循环:

package main
import "fmt"
func main() {
    for true {
    fmt.Printf("这是无限循环。\n");
}
}

Go字符串

在 Go 编程中广泛使用的字符串是只读字节。在 Go 编程语言中,字符串是切片。Go 平台提供了各种库来操作字符串。

  • unicode
  • 正则表达式
  • 字符串

创建字符串

var greeting = "Hello world!"

每当遇到代码中的字符串时,编译器将创建一个字符串对象,其值为“Hello world!”。字符串文字持有有效的 UTF-8 序列称为符文。字符串可保存任意字节。注意:字符串文字是不可变的,因此一旦创建后,字符串文字就不能更改了。

字符串长度

len(str)方法返回包含在字符串文字中的字节数。请参考以下代码示例 

package main
import "fmt"
func main() {
    var greeting = "Hello world!"
    fmt.Printf("String Length is: ")
    fmt.Println(len(greeting))
}

上面代码执行后,将产生以下结果:

String Length is : 12

连接字符串

strings 包包含一个用于连接多个字符串的 join()方法,其语法如下:strings.Join(sample, " ")Join 连接数组的元素以创建单个字符串。第二个参数是分隔符,放置在数组的元素之间。

案例:

package main

import (
	"strings"
	"fmt"
)

func main() {

	var a  []string = []string{"hello","world"}

	fmt.Println(strings.Join(a,"2"))

}

结果为:

hello2world

字符串输出格式化

Go 语言为 printf 传统中的字符串格式化提供了极好的支持。 以下是常见字符串 格式化任务的一些示例。 Go 提供了几种打印“动词”,设计用于格式化一般的值。 例如,打印 point 结构的 一个实例。 如果值是一个结构体,%+v 变体将包括结构体的字段名。 %#v 变体打印值的 Go 语法表示,即将生成该值的源代码片段。 要打印值的类型,请使用%T。格式化布尔是比较直截了当的。有许多格式化整数的 选项。对于标准的 base-10 格式化,请使用%d。

Go语言函数

函数是基本的代码块,用于执行一个任务。 Go 语言最少有个 main() 函数。 你可以通过函数来划分不同功能,逻辑上每个函数执行的是指定的任务。 函数声明告诉了编译器函数的名称,返回类型,和参数。 Go 语言标准库提供了多种可动用的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。如果我们传入的是字符串则返回字符串的长度,如果传入的是数组,则返回数组中包含的元素个数。 

函数定义

Go语言函数定义格式如下:

func function_name( [parameter list] ) [return_types] {   
 函数体 
} 

函数定义解析:

• func:函数由 func 开始声明 
• function_name:函数名称,函数名和参数列表一起构成了函数签名。 
• parameter list:参数列表,参数就像一个占位符,当函数被调用时,你可以将值传递给参
数,这个值被称为实际参数。参数列表指定的是参数类型、顺序、及参数个数。参数是可选 的,也就是说函数也可以不包含参数。 
• return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能 不需要返回值,这种情况下 return_types 不是必须的。 
• 函数体:函数定义的代码集合。

当有多个相同类型的连续参数时,可以省略类型参数的类型名称,直到声明该类型 的最后一个参数。例如:

func plusPlus(a, b, c int) int { 
    return a + b + c 
} 

示例:以下实例为 max() 函数的代码,该函数传入两个整型参数 num1 和 num2,并返回这两个参
数的最大值: 

/* 函数返回两个数的最大值 */ 
func max(num1, num2 int) int {    /* 声明局部变量 */ 
   var result int 
 
   if (num1 > num2) { 
      result = num1 
 
   } else { 
      result = num2 
   } 
   return result  
}

函数调用

当创建函数时,你定义了函数需要做什么,通过调用该函数来执行指定任务。 
调用函数,向函数传递参数,并返回值,例如:

package main 
 
import "fmt" 
 
func main() {    /* 定义局部变量 */ 
   var a int = 100 
   var b int = 200 
   var ret int 
 
   /* 调用函数并返回最大值 */ 
   ret = max(a, b) 
 
   fmt.Printf( "maxNum= : %d\n", ret ) 
} 
 
/* 函数返回两个数的最大值 */ 
func max(num1, num2 int) int {    /* 定义局部变量 */ 
   var result int 
 
   if (num1 > num2) { 
      result = num1 
   } else { 
      result = num2 
   } 
   return result  
} 

以上实例在 main() 函数中调用 max()函数,执行结果为: 

最大值是 : 200 

函数返回多个值

package main 
 
import "fmt" 
 
func swap(x, y string) (string, string) { 
   return y, x 
} 
 
func main() { 
   a, b := swap("Mahesh", "Kumar") 
   fmt.Println(a, b) 
} 

以上实例执行结果为:

Kumar Mahesh 

可变参数函数

可变参数的函数可以用任何数量的参数来调用。 例如,fmt.Println()就是一个常 见的可变函数。 下面的例子将任意数量的 int 作为参数。可变参数的函数可以通过单独的参数以通 常的方式调用。 如果已经在一个切片中有多个参数,使用 func(slice ...)函数将它们应用到一 个可变函数。 

package main

import "fmt"

// 这个函数可以传入任意数量的整型参数
func sum(nums ...int) {
    fmt.Print(nums, " ")
    total := 0
    for _, num := range nums {
        total += num
    }
    fmt.Println(total)
}

func main() {

    // 支持可变长参数的函数调用方法和普通函数一样
    // 也支持只有一个参数的情况
    sum(1, 2)
    sum(1, 2, 3)

    // 如果你需要传入的参数在一个切片中,像下面一样
    // "func(slice...)"把切片打散传入
    nums := []int{1, 2, 3, 4}
    sum(nums...)
}

函数形参的副本机制

默认情况下,Go 语言使用的是值传递,即在调用过程中不会影响到实际参数。 传递是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。 默认情况下,Go 语言使用的是值传递,即在调用过程中不会影响到实际参数。

以下定义了swap()函数

/* 定义相互交换值的函数 */ 
func swap(x, y int) int { 
   var temp int 
   temp = x /* 保存 x 的值 */ 
   x = y    /* 将 y 值赋给 x */ 
   y = temp /* 将 temp 值赋给 y*/ 
 
   return temp; 
} 

 接下来让我们使用值传递来调用swap()函数。

package main 
import "fmt"  
func main() { 
   /* 定义局部变量 */ 
   var a int = 100 
   var b int = 200 
 
   fmt.Printf("交换前 a 的值为 : %d\n", a ) 
   fmt.Printf("交换前 b 的值为 : %d\n", b ) 
 
   /* 通过调用函数来交换值 */ 
   swap(a, b) 
 
   fmt.Printf("交换后 a 的值 : %d\n", a ) 
   fmt.Printf("交换后 b 的值 : %d\n", b ) 

} 
 
/* 定义相互交换值的函数 */ 
func swap(x, y int) int { 
   var temp int 
 
   temp = x /* 保存 x 的值 */ 
   x = y    /* 将 y 值赋给 x */ 
   y = temp /* 将 temp 值赋给 y*/ 
 
   return temp; 
} 

以上代码执行结果为:

交换前 a 的值为 : 100 
交换前 b 的值为 : 200 
交换后 a 的值 : 100 
交换后 b 的值 : 200

参数的引用传递

引用传递是指在调用函数时将实际参数的地址传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。 引用传递指针参数传递到函数内,以下是交换函数 swap() 使用了引用传递: 

/* 定义交换值函数*/ 
func swap(x *int, y *int) { 
   var temp int 
   temp = *x    /* 保持 x 地址上的值 */  
   *x = *y      /* 将 y 值赋给 x */  
   *y = temp    /* 将 temp 值赋给 y */ 

 
} 
以下我们通过使用引用传递来调用 swap() 函数: 
package main 
 
import "fmt" 
 
func main() {    /* 定义局部变量 */ 
   var a int = 100 
   var b int= 200 
 
   fmt.Printf("交换前,a 的值 : %d\n", a )  
   fmt.Printf("交换前,b 的值 : %d\n", b ) 
 
   /* 调用 swap() 函数   
    * &a 指向 a 指针,a 变量的地址  
    * &b 指向 b 指针,b 变量的地址 
   */ 
   swap(&a, &b) 
 
   fmt.Printf("交换后,a 的值 : %d\n", a )  
   fmt.Printf("交换后,b 的值 : %d\n", b ) 
} 
 
func swap(x *int, y *int) { 
   var temp int  
   temp = *x    /* 保存 x 地址上的值 */   
   *x = *y      /* 将 y 值赋给 x */   
   *y = temp    /* 将 temp 值赋给 y */ 
}

执行结果为:

交换前,a 的值 : 100 
交换前,b 的值 : 200 
交换后,a 的值 : 200 
交换后,b 的值 : 100 

函数作为值

Go 语言可以很灵活的创建函数,并作为值使用。以下实例中我们在定义的函数中初始化一个变量,该函数仅仅是为了使用内置函数 math.sqrt() ,实例为: 
 

package main 
 
import ( 
   "fmt" 
   "math" 
) 
 
func main(){ 
   /* 声明函数变量 */ 
   getSquareRoot := func(x float64) float64 { 
      return math.Sqrt(x) 
   } 
 
   /* 使用函数 */ 
   fmt.Println(getSquareRoot(9)) 
 
} 

以上代码执行的结果为:3

匿名函数

Go 语言支持匿名函数,可作为闭包。匿名函数是一个"内联"语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必申明。 

以下实例中,我们创建了函数 getSequence() ,返回另外一个函数。该函数的目的是在闭包
中递增 i 变量,代码如下: 

package main 
 
import "fmt" 
 
func getSequence() func() int { 
   i:=0 
   return func() int { 
      i+=1 
     return i   
   } 
} 
 
func main(){ 
   /* nextNumber 为一个函数,函数 i 为 0 */ 
   nextNumber := getSequence()   
 
   /* 调用 nextNumber 函数,i 变量自增 1 并返回 */ 
   fmt.Println(nextNumber()) 
   fmt.Println(nextNumber()) 
   fmt.Println(nextNumber()) 
    
   /* 创建新的函数 nextNumber1,并查看结果 */ 
   nextNumber1 := getSequence()   

   fmt.Println(nextNumber1()) 
   fmt.Println(nextNumber1()) 
} 

以上代码的结果为:

1 
2 
3 
1 
2 

方法:包含了接收者的函数

Go 语言中同时有函数和方法。一个方法就是一个包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者是一个指针。所有给定类型的方法属于该类型的方法集。语法格式如下:

func (variable_name variable_data_type) function_name() [return_type]{    /* 函数体*/ 
} 

下面定义一个结构体类型和该类型的一个方法:

package main 
 
import ( 
   "fmt"   
) 
 
/* 定义结构体 */ 
type Circle struct { 
  radius float64 
} 
 
func main() { 
  var c1 Circle 
  c1.radius = 10.00 
 
  fmt.Println("Area of Circle(c1) = ", c1.getArea()) 
} 
 
//该 method 属于 Circle 类型对象中的方法 
func (c Circle) getArea() float64 {   //c.radius 即为 Circle 类型对象中的属性 
  return 3.14 * c.radius * c.radius 
} 

以上代码执行结果为:

Area of Circle(c1) =  314

猜你喜欢

转载自blog.csdn.net/The_Reader/article/details/84146913