mirror of
https://github.com/alrayyes/wiki.git
synced 2024-12-01 15:26:23 +00:00
178 lines
2.3 KiB
Markdown
178 lines
2.3 KiB
Markdown
---
|
|
id: 7ca10187-82d5-44fb-83a2-aa739c14cb24
|
|
title: Golang interfaces
|
|
---
|
|
|
|
# Basics
|
|
|
|
Go supports method interfaces:
|
|
|
|
``` go
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"math"
|
|
)
|
|
|
|
type Abser interface {
|
|
Abs() float64
|
|
}
|
|
|
|
func main() {
|
|
var a Abser
|
|
f := MyFloat(-math.Sqrt2)
|
|
v := Vertex{3, 4}
|
|
|
|
a = f // a MyFloat implements Abser
|
|
a = &v // a *Vertex implements Abser
|
|
|
|
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:
|
|
|
|
``` go
|
|
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"}
|
|
i.M()
|
|
}
|
|
```
|
|
|
|
# Handy interfaces to know about
|
|
|
|
## Stringer
|
|
|
|
``` go
|
|
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)
|
|
}
|
|
```
|
|
|
|
## Error
|
|
|
|
``` go
|
|
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",
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
if err := run(); err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
}
|
|
```
|
|
|
|
## Reader
|
|
|
|
``` go
|
|
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
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## Images
|
|
|
|
``` go
|
|
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())
|
|
}
|
|
```
|