1. 程式人生 > 其它 >go 語言控制檯輸入和go語言函式

go 語言控制檯輸入和go語言函式

go語言控制檯輸入及go的函式

目錄

Go 控制檯輸入,數值轉換,及隨機數

不同基礎型別之間的轉化

對於不同的基礎型別之間的轉化,Go提供了strconv包。它實現了字串與其他基本資料型別之間的轉化。其中最常用的數值轉化函式是 AtoiItoa,簡單瞭解下它的使用。

  • Atoi方法可以將字串型別的數值直接轉化為int型別的數值。
  • Itoa可以將int型別的數值轉化為 string型別的值

控制檯輸入

//控制檯輸入一個數值,進行資料大小的比較(注意,要在終端,使用go run的方式執行)
package main

import "fmt"

func main() {
	var (
		number int
	)
	//控制檯提示資訊
	fmt.Print("請輸入一個整數:")
	//控制檯輸入,輸入的內容直接賦值給變數.
	fmt.Scan(&number)
	fmt.Println("數值是:", number)
	fmt.Printf("資料型別是%T", number)
}



數值轉換

//控制檯輸入一個數值,進行資料大小的比較
package main

import (
	"fmt"
	"strconv"
)

func main() {
	var (
		//定義資料型別
		number string
	)
	//控制檯提示資訊
	fmt.Print("請輸入一個整數:")
	//控制檯輸入,輸入的內容直接賦值給變數.
	fmt.Scan(&number) //如果輸入10100,此時,輸入進來的時字串10100
	fmt.Println("數值是:", number)
	fmt.Printf("資料型別是%T\n", number)

	//資料型別轉換,string---->int
	//Atoi函式,接收字串型別數值,返回兩個數值。第一個數值是轉換後的,第二個數值是error錯誤提示資訊
	//我們可以使用空白識別符號 _ 來接收錯誤資訊
	value, _ := strconv.Atoi(number)
	fmt.Printf("轉換後資料型別是%T\n", value)
	//數值判斷
	if value > 100 {
		fmt.Println("數值較大")
	} else {
		fmt.Println("數值較小")
	}
}


//輸出結果:
控制檯輸入 10100
請輸入一個整數:10100
數值是: 10100
資料型別是string
轉換後資料型別是int
數值較大


隨機數

package main

import (
	"fmt"
	"math/rand"
	"time"
)

/*隨機數*/
func main() {
	// 隨機種子
	rand.Seed(time.Now().Unix())
	// 獲取10個隨機數
	for i := 0; i < 10; i++ {
		//左閉右開[0,100)
		value := rand.Intn(100)
		fmt.Println(value)
	}

}

//輸出結果:
89
9
86
95
91
80
6
81
24
90


例項

// 猜商品價格,商品高低,商品價格隨機生成[0-300),如果你輸入的價格大於商品價格,則提示價格過高
//如果輸入的價格低於商品價格,則提示價格過低。知道猜中商品價格為止。並統計猜的次數

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	var number, a int
	rand.Seed(time.Now().Unix())
	value := rand.Intn(301)
	for {
		fmt.Print("請輸入商品價格:")
		fmt.Scan(&number)
		fmt.Println("你猜的價格是:", number)
		a++
		if number == value {
			fmt.Println("你猜對了,商品價格是:", value)
			fmt.Println("你一共猜了", a, "次")
			break
		}
		if number < value {
			fmt.Println("抱歉,你猜小了")
		}
		if number > value {
			fmt.Println("抱歉,你猜大了")
		}
	}
}


// 猜商品價格,商品高低,商品價格隨機生成[0-300),如果你輸入的價格大於商品價格,則提示價格過高
//如果輸入的價格低於商品價格,則提示價格過低。知道猜中商品價格為止。並統計猜的次數

package main

import (
	"fmt"
	"math/rand"
	"time"
)

func main() {
	//number用來接收控制檯輸入,count用來統計使用者猜的次數
	var number, count int
	//生成商品價格
	rand.Seed(time.Now().Unix())
	value := rand.Intn(301)
	for {
		fmt.Print("請輸入商品價格:")
		fmt.Scan(&number)
		fmt.Println("你猜的價格是:", number)
		//使用者每猜一次,count值加一
		count++
		switch {
		case number == value:
			fmt.Printf("你猜對了,商品價格是:%d\n一共猜了%d次", value, count)
			//使用者猜對,則退出
			//goto end 使用goto 或者return 都可以
			return
		case number > value:
			fmt.Println("你猜大了")
		default:
			fmt.Println("你猜小了")
		}
	}
	//end:
}


package main

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

func main() {
	fmt.Println("請輸入內容:")
	str1 := getInput()
	fmt.Println(str1)
}

//緩衝區控制檯輸入
func getInput() string {
	//建立緩衝區,並且bufio緩衝區從控制檯讀取輸入資訊
	in := bufio.NewReader(os.Stdin)

	//從緩衝區中讀取字串資訊
	str, _, err := in.ReadLine()
	if err != nil {
		return err.Error()
	}
	return string(str)
}



package main

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

func main() {
	fmt.Println("請輸入內容:")
	str1 := getStrInput()
	fmt.Println(str1)
}

func getStrInput() string {
	var str string
	//建立bufio緩衝區,利用NewScanner載入控制檯輸入
	in := bufio.NewScanner(os.Stdin)
	if in.Scan() {
		str = in.Text()
	} else {
		str = "not found"
	}
	return str
}



Go 語言函式

函式是基本的程式碼塊,用於執行一個任務。

Go 語言最少有個 main() 函式。

你可以通過函式來劃分不同功能,邏輯上每個函式執行的是指定的任務。

函式宣告告訴了編譯器函式的名稱,返回型別,和引數。

Go 語言標準庫提供了多種可動用的內建的函式。例如,len() 函式可以接受不同型別引數並返回該型別的長度。如果我們傳入的是字串則返回字串的長度,如果傳入的是陣列,則返回陣列中包含的元素個數。

  • 內建函式:安裝完go編譯器就可以直接被呼叫的
  • 使用者自定義函式: 名字自行命名 (注意大小小控制權限)
  • 外掛中的函式:安裝地方元件,才擁有的函式,

函式定義

Go 語言函式定義格式如下:

func function_name( [parameter list] ) [return_types] {
   函式體
}

函式定義解析:

  • func:函式由 func 開始宣告
  • function_name:函式名稱,引數列表和返回值型別構成了函式簽名。
  • parameter list:引數列表,引數就像一個佔位符,當函式被呼叫時,你可以將值傳遞給引數,這個值被稱為實際引數。引數列表指定的是引數型別、順序、及引數個數。引數是可選的,也就是說函式也可以不包含引數。
  • return_types:返回型別,函式返回一列值。return_types 是該列值的資料型別。有些功能不需要返回值,這種情況下 return_types 不是必須的。
  • 函式體:函式定義的程式碼集合。

//無參,無返回值
func test (){
}

//傳參,有返回值
//傳遞的引數的引數型別,要和函式定義的引數值型別相同。定義了int 型別資料,就只能傳遞int型別資料進入
funt test(a int,b int) int {
  //注意,return 定義的返回值,要和函式定義的返回值型別一樣。比如這裡,定義了返回值型別為int,則return 返回值就只能是int
  return n
}

//傳參,有多個返回值
funt result(a int,b int)(int,int){
  return a+b,a-b
}

例項

以下例項為 max() 函式的程式碼,該函式傳入兩個整型引數 num1 和 num2,並返回這兩個引數的最大值:

/* 函式返回兩個數的最大值 */
// 小括號和大括號之間的int ,是定義函式返回值的資料型別
func max(num1, num2 int) int {
   /* 宣告區域性變數 */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
  //return 返回值,要和定義的返回值資料型別相同
   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( "最大值是 : %d\n", ret )
}

/* 函式返回兩個數的最大值 */
func max(num1, num2 int) int {
   /* 定義區域性變數 */
   var result int

   if (num1 > num2) {
      result = num1
   } else {
      result = num2
   }
   return result
}

//輸出結果:
最大值是 : 200

package main

import "fmt"

func main() {
	Test(10, 20, "兩數求和值為:")
}

//多引數傳入
func Test(a, b int, c string) {

	fmt.Println(c, a+b)
}

//輸出為:
兩數求和值為: 30


函式返回多個值

Go 函式可以返回多個值,例如:

//示例:函式返回多個值
package main

import "fmt"

func main() {
	a, b := mutil_value(10, 20)  //10,20 為實際引數
	fmt.Printf("兩個數項加是:%d,兩個數相乘是%d", a, b)
}

//num1,num2 形式引數,定義傳入引數的資料型別
func mutil_value(num1, num2 int) (int, int) {
	result1 := num1 + num2
	result2 := num1 * num2
	return result1, result2
}

//輸出結果:
兩個數項加是:30,兩個數相乘是200

package main

import "fmt"

func main() {
  //函式有多個返回值,但是隻想接收一個,可以使用空白識別符號
	_, b := Test(10, 20)
	fmt.Printf("兩數積是%d", b)
}

//多個返回值
func Test(a, b int) (int, int) {
	result1 := a + b
	result2 := a * b
	return result1, result2
}

//輸出結果
兩數積是200

函式引數

函式如果使用引數,該變數可稱為函式的形參。

形參就像定義在函式體內的區域性變數。

呼叫函式,可以通過兩種方式來傳遞引數:

傳遞型別 描述
值傳遞 值傳遞是指在呼叫函式時將實際引數複製一份傳遞到函式中,這樣在函式中如果對引數進行修改,將不會影響到實際引數。
引用傳遞 引用傳遞是指在呼叫函式時將實際引數的地址傳遞到函式中,那麼在函式中對引數所進行的修改,將影響到實際引數。

預設情況下,Go 語言使用的是值傳遞,即在呼叫過程中不會影響到實際引數。


Go 語言函式值傳遞值


傳遞是指在呼叫函式時將實際引數複製一份傳遞到函式中,這樣在函式中如果對引數進行修改,將不會影響到實際引數。

預設情況下,Go 語言使用的是值傳遞,即在呼叫過程中不會影響到實際引數。

package main

import "fmt"

func main() {
	var (
		num1 = 10
		num2 = 20
	)
	fmt.Println("交換前主函式")
	fmt.Printf("num1=%d\nnum2=%d\n", num1, num2)
	//呼叫函式,傳入實參
	swap(num1, num2)
	fmt.Println("交換後主函式")
	fmt.Printf("num1=%d\nnum2=%d\n", num1, num2)
}

//兩個數值交換
func swap(a, b int) {
	a, b = b, a
	fmt.Println("swap函式內", a, b)
}


//輸出結果
交換前主函式
num1=10
num2=20
swap函式內 20 10
交換後主函式
num1=10
num2=20

程式中使用的是值傳遞, 所以兩個值並沒有實現互動,我們可以使用 引用傳遞來實現交換效果。




Go 語言函式引用傳遞值

引用傳遞是指在呼叫函式時將實際引數的地址傳遞到函式中,那麼在函式中對引數所進行的修改,將影響到實際引數。

以下我們通過使用引用傳遞來呼叫 swap() 函式:

package main

import "fmt"

func main() {
	var (
		num1 = 11
		num2 = 22
	)
	fmt.Println("交換前兩數值")
	fmt.Printf("num1=%d\nnum2=%d\n", num1, num2)
	swap(&num1, &num2)
	fmt.Println("交換後兩數值")
	fmt.Printf("num1=%d\nnum2=%d\n", num1, num2)
}

//引用型別傳參
func swap(a, b *int) {
	*a, *b = *b, *a
}

//輸出結果:
交換前兩數值
num1=11
num2=22
交換後兩數值
num1=22
num2=11


函式用法

函式用法 描述
函式作為另外一個函式的實參 函式定義後可作為另外一個函式的實引數傳入
閉包 閉包是匿名函式,可在動態程式設計中使用
方法 方法就是一個包含了接受者的函式


Go 語言函式作為實參與go語言數學包

Go 語言可以很靈活的建立函式,並作為另外一個函式的實參。以下例項中我們在定義的函式中初始化一個變數,該函式僅僅是為了使用內建函式 math.sqrt(),例項為:

package main

import (
	"fmt"
	"math"
)

func main() {
	//函式變數(匿名函式)
	result := func(x float64) float64 {
		return math.Sqrt(x)
	}
	//直接使用變數名呼叫函式
	fmt.Println(result(9))
}

//輸出結果:
3

go語言數學包

//go語言數學包
package main

import (
	"fmt"
	"math"
)

func main() {
	//數學包
	fmt.Println("-10的絕對值:", math.Abs(-10))
	fmt.Println("5.2向上取整:", math.Ceil(5.2))
	fmt.Println("5.8向下取整:", math.Floor(5.8))
	fmt.Println("11除以3的餘數:", math.Mod(11, 3))
	fmt.Println("取整數,取小數")
	fmt.Println(math.Modf(5.26))
	fmt.Println("3的2次方", math.Pow(3, 2))
	fmt.Println("10的4次方", math.Pow10(4))
	fmt.Println("27的開立方", math.Cbrt(27))
	fmt.Println("圓周率", math.Pi)
}

//輸出結果:
-10的絕對值: 10
5.2向上取整: 6
5.8向下取整: 5
11除以3的餘數: 2
取整數,取小數
5 0.2599999999999998
3的2次方 9
10的4次方 10000
27的開立方 3
圓周率 3.141592653589793

回撥函式

回撥函式作為初始函式的引數傳入

當呼叫初始函式的時候,自動呼叫回撥函式

初始函式---->回撥函式

package main

import "fmt"

//宣告形式函式
type cback func(int) int

func main() {
	//對回撥函式進行了隱匿,起到了安全保護作用,提高程式執行效率
	test_back(1, call_back)
}

//測試函式,用來呼叫回撥函式
//將宣告的形式函式,作為形參
func test_back(x int, f cback) {
	fmt.Println("test_back函式,語句1")
	f(x)
	fmt.Println("test_back函式,語句2")
}

//回撥函式
func call_back(a int) int {
	fmt.Println("回撥函式call_back:", a)
	return a
}



//輸出結果:
test_back函式,語句1
回撥函式call_back: 1
test_back函式,語句2

package main

import (
	"fmt"
)

//宣告形式函式
type cback func(int) int

func main() {
	//對回撥函式進行了隱匿,起到了安全保護作用,提高程式執行效率
	test_back(1, call_back)
	test_back(2, func(b int) int {
		fmt.Println("匿名回撥函式:", b)
		return b
	})
}

//測試函式,用來呼叫回撥函式
//將宣告的形式函式,作為形參
func test_back(x int, f cback) {
	fmt.Println("test_back函式,語句1")
	f(x)
	fmt.Println("test_back函式,語句2")
}

//回撥函式
func call_back(a int) int {
	fmt.Println("回撥函式call_back:", a)
	return a
}


//輸出結果:
test_back函式,語句1
回撥函式call_back: 1
test_back函式,語句2
test_back函式,語句1
匿名回撥函式: 2
test_back函式,語句2



Go 語言函式閉包

閉包:一個函式與其相關的引用環境組成的一個整體


Go 語言支援匿名函式,可作為閉包。匿名函式是一個"內聯"語句或表示式。匿名函式的優越性在於可以直接使用函式內的變數,不必申明。


//演示閉包
package main

import "fmt"

//函式close_package, 其返回值是 func(int) int
func close_package() func(int) int {
  //閉包開始
  //定義一個變數 n
	var n int = 10
  // return 返回的是一個匿名函式.
  //這個匿名函式引用了其函式本身外的變數n.因此,這個函式和 n 形成了一個整體,構成了閉包
	return func(x int) int {
    //呼叫函式外部的變數n
		n += x
		return n
	}
  //閉包結束
}

func main() {
	
	f := close_package()
	fmt.Println(f(1))    //11
	fmt.Println(f(2))    //13
	fmt.Println(f(3))    //16
}

//輸出結果:
11
13
16


  • 一個函式close_package ,其返回值是一個函式
  • 作為返回值的函式,引用了外部函式close_package裡定義的變數n .這個外部函式的變數n 就和作為返回值的函式,形成了一個整體,構成了閉包.
  • 當反覆呼叫外部函式close_package 裡的變數n 時,n 只會初始化一此,因此,每呼叫一次,就進行累計

package main

import "fmt"

func main() {
	number1 := close_package()
	fmt.Println("number1 閉包執行")
	fmt.Println(number1())
	fmt.Println(number1())
	fmt.Println(number1())
	number2 := close_package()
	fmt.Println("number2 閉包執行")
	fmt.Println(number2())
	fmt.Println(number2())
	fmt.Println(number2())
}

//匿名函式作為close_package 函式的返回值,
func close_package() func() int {
  //在函式close_package 裡定義變數i
	i := 1
	// 返回 執行匿名函式 閉包結構
	return func() int {
   //雖然變數i 是在此匿名函式外部定義的,但是匿名函式內部依舊可見。
	  //匿名函式引用函式外變數.因此,匿名函式和變數i 形成了一個整體,構成閉包
		i++
		return i
	}
}


//輸出結果:
number1 閉包執行
2
3
4
number2 閉包執行
2
3
4



Go 語言函式方法

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("圓的面積 = ", c1.getArea())
}

//該 method 屬於 Circle 型別物件中的方法,只有Circle 能呼叫
//c 為Circle的例項物件
func (c Circle) getArea() float64 {
  //c.radius 即為 Circle 型別物件中的屬性
  return 3.14 * c.radius * c.radius
}

//輸出結果:
圓的面積 =  314


在example1目錄下,有兩個目錄car 和 main. car 目錄下有car.go 檔案, main目錄下有main.go檔案

// car 包,car.go定義結構體和方法
package car

import "fmt"

//定義結構體
type Car struct {
	//定義屬性
	Name  string
	Color string
}

//函式方法
func (c Car) Call() {
	// (c Car ) 等同於 c := new(Car)
	fmt.Printf("%s 品牌的汽車,顏色是%s,正在鳴笛\n", c.Name, c.Color)
}
func (c Car) Run() {
	fmt.Printf("%s 品牌的汽車,顏色是%s,正在行駛\n", c.Name, c.Color)
}

//main包,main.go 載入car 包,呼叫結構體,進行例項化
package main

import "dev_code/day9/example1/car"

func main() {
	//例項化
	c1 := new(car.Car)
	c1.Name = "賓士"
	c1.Color = "黑色"
	c1.Call()
	c2 := new(car.Car)
	c2.Name = "寶馬"
	c2.Color = "白色"
	c2.Run()
}


// main.go 執行結果
賓士 品牌的汽車,顏色是黑色,正在鳴笛
寶馬 品牌的汽車,顏色是白色,正在行駛