Go语言基础
Posted 想考北航的小刺猬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go语言基础相关的知识,希望对你有一定的参考价值。
Method
- go语言没有类这个概念,但是但可以在类型上定义method,method是一个带有指定receiver参数的函数,receiver出现在自己的参数列表中,并且位于func关键字和method名之间,Abs方法有一个类型为Vertex命名为v的receiver。
package main
import(
"fmt"
"math"
)
type Vertex struct
X, Y float64
func (v Vertex) Abs() float64
return math.Sqrt(v.X*v.X + v.Y*v.Y)
func main()
v := Vertex3, 4
fmt.Println(v.Abs())
func add(x, y int) int
- method只是一个带有receiver参数的函数
- 也能够用非结构类型定义method,但是不能用内置的类型,比如说int、float64等
package main
import(
"fmt"
"math"
)
type MyFloat float64
func (f MyFloat)Abs()float64
if f < 0
return float64(-f)
return float64(f)
func main()
f := MyFloat(-math.Sqrt2)
fmt.Println(f.Abs())
Pointer receivers
声明一个指针receiver的method
package main
import(
"fmt"
"math"
)
type Vertex struct
X,Y float64
func (v Vertex)Abs()float64
return math.Sqrt(v.X*v.X + v.Y*v.Y)
func (v *Vertex) Scale(f float64)
v.X = v.X * f
v.Y = v.Y * f
func main()
v := Vertex3, 4
v.Scale(10)
fmt.Println(v.Abs())
- v.Scale(2)等价于(&v).Scale(2),Go会将第一种自动翻译为第二种
- 选择指针receiver可以更加高效,避免复制参数,便于修改数值。
Interfaces
- 一个接口类型定义为一系列method signatures的集合,可以理解将一系列方法定位为同一个名称,根据receiver不同来区分。
package main
import(
"fmt"
"math"
)
type Abser interface
Abs() float64
func main()
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex3, 4
//a = f
a = &v
//a = v
fmt.Println(a.Abs())
type MyFloat float64
func (f MyFloat) Abs() float64
if f < 0
return float64(-f)
return float64(f)
type Vertex struct
X,Y float64
func (v *Vertex) Abs() float64
return math.Sqrt(v.X*v.X + v.Y*v.Y)
Interfaces are implemented implicitly
- 接口隐式实现,一个类型通过实现接口中的方法来实现接口,没有“implements”这种关键字。隐式接口将定义冲实现当中解耦,不需要预先安排就能出现在任何package中
package main
import "fmt"
type I interface
M()
type T struct
S string
// This method means type T implements the interface I,
// but we don't need to explicitly declare that it does so.
func (t T) M()
fmt.Println(t.S)
func main()
var i I = T"hello"//用T类型实现接口I
i.M()
- 接口可以被认为成值和接口的元组(value, type)
- 对应类型用接口中对应类型的方法,nil值的receiver也能调用对应类型的方法
package main
import "fmt"
type I interface
M()
type T struct
S string
func (t *T) M()
if t == nil
fmt.Println("<nil>")
return
fmt.Println(t.S)
func main()
var i I
var t *T
i = t
describe(i)
i.M()
i = &T"hello"
describe(i)
i.M()
func describe(i I)
fmt.Printf("(%v, %T)\\n", i, i)
- 直接用没有指定类型的接口,会产生超时错误,因为没有类型来指定要调用哪个具体的方法
package main
import "fmt"
type I interface
M()
func main()
var i I
describe(i)
i.M()
func describe(i I)
fmt.Printf("(%v, %T)\\n", i, i)
//结果
(<nil>, <nil>)
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x482161]
goroutine 1 [running]:
main.main()
/tmp/sandbox957396350/prog.go:12 +0x61
The Empty interface
- 没有方法的接口是空接口:interface
- 一个空接口可以接收任何的类型的值,主要用于处理不确定类型的值
package main
import(
"fmt"
"math"
)
func main()
var i interface
describe(i)
i = 42
describe(i)
i = "hello"
describe(i)
func describe(i interface)
fmt.Printf("(%v, %T)\\n", i , i)
//结果
(<nil>, <nil>)
(42, int)
(hello, string)
Type assertions
- 类型断言:t := i.(T),如果接口i基础值包含类型T,那么t就保存对应的类型的值。如果不包含就会引起一个panic
- 测试是否接口值包含一个具体的值,一个类型断言可以返回两个值:基础值和一个布尔值,布尔值保存断言是否成功(True or False) t, ok := i.(T),此时如果断言不成功也不会产生panic。
package main
import "fmt"
func main()
var i interface = "hello"
s := i.(string)
fmt.Println(s)
s, ok := i.(string)
fmt.Println(s, ok)
f, ok := i.(float64)
fmt.Println(f, ok)
f = i.(float64) // panic
fmt.Println(f)
Stringers
最常见的接口之一是fmt包定义的Stringer。
type Stringer interface
String() string
package main
import "fmt"
type Person struct
Name string
Age int
func (p Person) String() string
return fmt.Sprintf("%v (%v years)", p.Name, p.Age)
func main()
a := Person"Arthur Dent", 42
z := Person"Zaphod Beeblebrox", 9001
fmt.Println(a, z)
IP转化的练习
package main
import "fmt"
type IPAddr [4]byte
// TODO: Add a "String() string" method to IPAddr.
func (ip IPAddr)String() string
return fmt.Sprintf("%v.%v.%v.%v", ip[0], ip[1], ip[2], ip[3])
func main()
hosts := map[string]IPAddr
"loopback": 127, 0, 0, 1,
"googleDNS": 8, 8, 8, 8,
for name, ip := range hosts
fmt.Printf("%v: %v\\n", name, ip)
Errors
error也是一个内置的接口,也是在fmt包中,函数经常返回一个error值
type error interface
Error() string
package main
import (
"fmt"
"time"
)
type MyError struct
When time.Time
What string
func (e *MyError) Error() string
return fmt.Sprintf("at %v, %s",
e.When, e.What)
func run() error
return &MyError
time.Now(),
"it didn't work",
//返回值格为MyError结构,出现错误的时候调用NyError类型的Error()函数
func main()
if err := run(); err != nil
fmt.Println(err)
Readers
- io package指定了io.Reader接口。
- Read Method:func (T) Read(b []byte) (n int, err error)
package main
import (
"fmt"
"io"
"strings"
)
func main()
r := strings.NewReader("Hello, Reader!")
b := make([]byte, 8)
for
n, err := r.Read(b)
fmt.Printf("n = %v err = %v b = %v\\n", n, err, b)
fmt.Printf("b[:n] = %q\\n", b[:n])
if err == io.EOF
break
Image
image package定义了Image接口
package image
type Image interface
ColorModel() color.Model
Bounds() Rectangle
At(x, y int) color.Color
package main
import (
"fmt"
"image"
)
func main()
m := image.NewRGBA(image.Rect(0, 0, 100, 100))
fmt.Println(m.Bounds())
fmt.Println(m.At(0, 0).RGBA())
以上是关于Go语言基础的主要内容,如果未能解决你的问题,请参考以下文章