ゴー言語は、関数やメソッドの両方を持っています!
機能:プログラムは、主な機能が含まれている必要があります。主な機能は、任意のパラメータと戻り値を持つことはできません!
例1.定義する方法:
FUNC最大(NUM1、NUM2のINT) INT {// 同じパラメータタイプは、一種類のみ書き込むことができ
、戻り値の後者のタイプの// int型の代表的な
/ *ローカル変数を定義* /
VARのINT結果
IF(NUM1> NUM2)を{
結果NUM1 =
} {それ以外の
結果= NUM2
}
リターン結果
}
-------------------------------------- ----
FUNC SSSSS(INT X、Y列)(文字列、整数){
Y、Xを返します
}
-------------------------- ----------------
FUNC SumAndProduct(A、Bはint)(ADD INTは乗算をINT){
追加= A B +
逓倍は、* Bが=
リターン
}
-------------------------------------------------- ------------
××××××インポート(
"FMT"
"数学"
)
/ *関数宣言変数* /
getSquareRoot:FUNC =(X用のfloat64){リターンMath.sqrtをのfloat64(X )}
/ *使用関数* /
fmt.Println(getSquareRoot(9))
関数の戻り値が複数存在する2.ブランク識別子_ /これらの値を削除するために使用することができます。
前記可変パラメータ-可変パラメータを受信すると関数である形状パラメータの不確実性の量関数。。。
定義方法:
FUNC_NAME FUNC(アルギニン... INT){...} //この関数のArgここで、INTフラグは、int型の可変数の引数を受け取ることができます
//関数本体、argはint型のスライスである(argは引数に置き換えることができます)
値と基準送信によって渡さ - 渡された4パラメータ
値が渡された -ああ渡された共通の値です。。
参照によって渡されたポインタを使用して- - 物質は、値によって渡されます。。。
var x int = 2 则若实参为地址 &x, 则形参为 *int 型。 传内存地址比较轻量级(8bytes),我们可以用指针传递体积大的结构体。 如果用参数值传递的话, 在每次copy上面就会花费相对较多的系统开销(内存和时间)。 所以当你要传递大的结构体的时候,用指针是一个明智的选择。
5 闭包: Go语言支持匿名函数,闭包的表现形式一般是匿名函数,通过函数返回一个函数。 闭包会使函数中的变量都被保存在内存中!消耗内存。
×××只要闭包还在使用,那么被闭包引用的变量就会一直存在!!!
func getSequence() func() int { i := 0 return func() int { i += 1 return i } } func main() { /* nextNumber 为一个函数 */ // var nextNumber = getSequence() 或者 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
6. 可以声明一个函数类型;然后函数就可以作为值传递了! type testInt func(int) bool // 声明了一个函数类型testInt, 接收一个int型参数,返回值为bool类型
7. panic和recover: Go语言没有像Java那样的异常机制,不能抛出异常,而是使用panic和recover机制。 panic(...)——当函数F调用panic,函数F的执行被中断,但是F中的延迟函数会正常执行,然后F返回到调用它的地方。在调用的地方,F的行为就像调用了panic。这一过程继续向上,直到发生panic的goroutine中所有调用的函数返回,此时程序退出。
recover()让进入恐慌的goroutine恢复过来。recover仅在延迟函数中有效。在正常的执行过程中,调用recover会返回nil,并且没有其它任何效果。
方法:
1. 定义方法: func (t Type) method(parameter list) { //其中t是一个接收器,可以接收结构体或者非结构体类型 ... }
示例代码:
package main
import "fmt"
type Employee struct {
name string
salary int
currency string
}
/*
displaySalary()的方法接收器为Employee结构体类型
*/
func (e Employee) displaySalary() {
fmt.Printf("Salary of %s is %s%d", e.name, e.currency, e.salary)
}
func main() {
emp1 := Employee {
name: "Sam Adolf",
salary: 5000,
currency: "$",
}
emp1.displaySalary() // 调用displaySalary() 方法
}
可以定义相同的方法名:相同名称的方法可以在不同的类型上定义,而具有相同名称的函数是不允许的!
package main
import (
"fmt"
"math"
)
type Rectangle struct {
width, height float64
}
type Circle struct {
radius float64
}
// 该 method 属于 Rectangle 类型对象中的方法
func (r Rectangle) area() float64 {
return r.width * r.height
}
// 该 method 属于 Circle 类型对象中的方法
func (c Circle) area() float64 {
return c.radius * c.radius * math.Pi
}
func main() {
r1 := Rectangle{12, 2}
r2 := Rectangle{9, 4}
c1 := Circle{10}
c2 := Circle{25}
fmt.Println("Area of r1 is: ", r1.area())
fmt.Println("Area of r2 is: ", r2.area())
fmt.Println("Area of c1 is: ", c1.area())
fmt.Println("Area of c2 is: ", c2.area())
}
2. 变量作用域:
函数内定义的变量称为局部变量,它们的作用域只在函数体内(参数和返回值变量也是局部变量)
函数外定义的变量称为全局变量,首字母大写全局变量可以在整个包甚至外部包(被导出后)使用。
3. 用指针可以改变值!!
package main
import (
"fmt"
)
type Rectangle struct {
width, height int
}
func (r *Rectangle) setVal() {
r.height = 20
}
func main() {
p := Rectangle{1, 2}
s := p // 此时只是将p的数据拷贝给s了一份,即二者并不是指向同一数据的关系
// p是p,s是s,改变p不会影响s
p.setVal()
mt.Println(p.height, s.height)
}
4. 继承: 如果匿名字段实现了一个method,那么包含这个匿名字段的struct也能调用该method.
type Human struct { name string age int phone string } type Student struct { Human // 匿名字段 school string } type Employee struct { Human //匿名字段 company string } func (h *Human) SayHi() { fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone) } func main() { mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"} sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"} mark.SayHi() sam.SayHi() }
5. 重写: (就近原则)
package main
import "fmt"
type Human struct {
name string
age int
phone string
}
type Student struct {
Human //匿名字段
school string
}
type Employee struct {
Human //匿名字段
company string
}
//Human定义method
func (h *Human) SayHi() {
fmt.Printf("Hi, I am %s you can call me on %s\n", h.name, h.phone)
}
//Employee的method重写Human的method
func (e *Employee) SayHi() {
fmt.Printf("Hi, I am %s, I work at %s. Call me on %s\n", e.name,
e.company, e.phone) // Yes you can split into 2 lines here.
}
func main() {
mark := Student{Human{"Mark", 25, "222-222-YYYY"}, "MIT"}
sam := Employee{Human{"Sam", 45, "111-888-XXXX"}, "Golang Inc"}
mark.SayHi()
sam.SayHi()
}
结果:
Hi, I am Mark you can call me on 222-222-YYYY
Hi, I am Sam, I work at Golang Inc. Call me on 111-888-XXXX