生活所迫,入门一下Go
- 很奇葩的第一点,接口
go
package main
import (
"fmt"
)
// 定义一个接口
type Shape interface {
Area() float64
}
// 定义一个矩形类型
type Rectangle struct {
Width float64
Height 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
奇葩的第三点:数组的写法
go
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),则该方法是私有的,只能在同一包内部访问,不能在包外部访问。
go
package shape
func Description(name string) string {
return "The person name is: " + name
}
func secretName(name string) string {
return "Do not share"
}
4 . 奇葩第五点:错误处理。这一点也是早有耳闻了。
go
func main() {
resp, err := http.Get("http://example.com")
if err != nil {
fmt.Println(err)
//return
}
fmt.Println(resp)
num := 5
if 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, 可以与另一个函数并发执行
go
func main() {
go task()
fmt.Println("main")
time.Sleep(time.Second * 2)
}
func task() {
fmt.Println("concurrent")
}
go channel:在两个go routine之间传递数据。 写法也挺怪的。
go
package main
import "fmt"
func main(){
c := make(chan string) // 创建channel, 可以发送string类型的数据
go func(){ c <- "hello" }() // 发送端
msg := <-c // 接收端
fmt.Println(msg)
}
让创建的goroutine发送数据:
go
package main
import (
"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 ,只有一个会执行
go
select {
case <-channel1:
// 从channel1接收到数据时执行的代码
case data := <-channel2:
// 从channel2接收到数据时执行的代码
case channel3 <- value:
// 将value发送到channel3时执行的代码
default:
// 如果没有通道操作准备就绪,执行的默认操作
}
go
package main
import (
"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)
}
}