go 語言控制檯輸入和go語言函式
go語言控制檯輸入及go的函式
目錄Go 控制檯輸入,數值轉換,及隨機數
不同基礎型別之間的轉化
對於不同的基礎型別之間的轉化,Go提供了strconv包。它實現了字串與其他基本資料型別之間的轉化。其中最常用的數值轉化函式是 Atoi
和Itoa
,簡單瞭解下它的使用。
-
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 執行結果
賓士 品牌的汽車,顏色是黑色,正在鳴笛
寶馬 品牌的汽車,顏色是白色,正在行駛