生活所迫,入门一下Go
- 很奇葩的第一点,接口
package mainimport ("fmt"
)// 定义一个接口
type Shape interface {Area() float64
}// 定义一个矩形类型
type Rectangle struct {Width float64Height float64
}// 矩形类型实现Shape接口的Area方法
func (r Rectangle) Area() float64 {return r.Width * r.Height
}// 定义一个圆形类型
type Circle struct {Radius float64
}// 圆形类型实现Shape接口的Area方法
func (c Circle) Area() float64 {return 3.14159265359 * c.Radius * c.Radius
}func main() {// 创建一个矩形对象rectangle := Rectangle{Width: 4, Height: 5}// 创建一个圆形对象circle := Circle{Radius: 3}// 使用接口来计算不同形状的面积shapes := []Shape{rectangle, circle}for _, shape := range shapes {fmt.Printf("Area of the shape is: %.2f\n", shape.Area())}
}
gpt这么解释: Go语言中的接口实现是隐式的,而不是明确的。这意味着你不需要显式声明一个类型实现了某个接口,只要这个类型提供了接口中定义的所有方法,它就被认为实现了该接口。这是Go语言的一种灵活而简洁的设计。
- 奇葩的第二点:没有for in,但是有range
奇葩的第三点:数组的写法
func main() {rec := Rectangle{width: 2.0, height: 3.0}cir := Circle{radius: 2.0}shapes := []Shape{rec, cir}for index, shapes := range shapes {fmt.Println(index, shapes.Area())}}
- 奇葩的第四点:方法依靠方法名决定权限:public or private
大写开头的方法为public,可以被外部调用;小写开头则为private,不能被外部调用
● 如果方法名以大写字母开头(例如GetName),则该方法是公开的,可以在包外部访问。
● 如果方法名以小写字母开头(例如calculate),则该方法是私有的,只能在同一包内部访问,不能在包外部访问。
package shapefunc Description(name string) string {return "The person name is: " + name
}
func secretName(name string) string {return "Do not share"
}
4 . 奇葩第五点:错误处理。这一点也是早有耳闻了。
func main() {resp, err := http.Get("http://example.com")if err != nil {fmt.Println(err)//return}fmt.Println(resp)num := 5if inc, err := Increment(num); err != nil {fmt.Printf("failed number: %v, error message: %v\n", inc, err)} else {fmt.Printf("increment successfully, num is %v \n", inc)}
}func Increment(n int) (int, error) {if n < 0 {return n, errors.New("error")}return n + 1, nil
}
- go最精彩的点:Go routine, 可以与另一个函数并发执行
func main() {go task()fmt.Println("main")time.Sleep(time.Second * 2)}func task() {fmt.Println("concurrent")
}
go channel:在两个go routine之间传递数据。 写法也挺怪的。
package mainimport "fmt"func main(){c := make(chan string) // 创建channel, 可以发送string类型的数据go func(){ c <- "hello" }() // 发送端msg := <-c // 接收端fmt.Println(msg)
}
让创建的goroutine发送数据:
package mainimport ("fmt"
)func main() {ch := make(chan string)go sc(ch)fmt.Println(<-ch)
}// sc函数:只能发送数据给 channel,不能接收数据
func sc(ch chan<- string) {ch <- "hello"
}
select等待多个channel:select +case ,只有一个会执行
select {
case <-channel1:// 从channel1接收到数据时执行的代码
case data := <-channel2:// 从channel2接收到数据时执行的代码
case channel3 <- value:// 将value发送到channel3时执行的代码
default:// 如果没有通道操作准备就绪,执行的默认操作
}
package mainimport ("fmt""time"
)func main() {ch1 := make(chan string)ch2 := make(chan string)go func() {time.Sleep(2 * time.Second)ch1 <- "Message from channel 1"}()go func() {time.Sleep(1 * time.Second)ch2 <- "Message from channel 2"}()select {case msg1 := <-ch1:fmt.Println(msg1)case msg2 := <-ch2:fmt.Println(msg2)}
}