preface
Many object-oriented languages have similar interface concepts, but the interface type in Go is unique in that it is implemented implicitly and doesn’t need to be written out like Java does
Implementation and use of interfaces
A type implements an interface if it has all the methods that an interface needs.
Excerpt – Novice programming
/* Define the interface */
type interface_name interface {
method_name1 [return_type]
method_name2 [return_type]
method_name3 [return_type]
...
method_namen [return_type]}
/* Define the XXX data structure type */
type struct_name xxx
/* Implement the interface method */
func (struct_name_variable struct_name) method_name1(a) [return_type] {
The /* method implements */}...func (struct_name_variable struct_name) method_namen(a) [return_type] {
The /* method implements */}
Copy the code
A case study
package main
import "fmt"
type Animal interface {
run() string
fly() string
eat() string
}
// Define the structure
type Dog struct {
name string
age int
}
func (dog Dog) fly(a) string {
fmt.Println("Dog's name is", dog.name, "He cannot fly.Because he is dog,dog cannot fly ")
return ""
}
// Implement the interface
func (dog Dog) run(a) string {
fmt.Println("Dog's name is", dog.name, "He can run. He is", dog.age, "Old")
return ""
}
func (dog Dog) eat(a) string {
fmt.Println("Dog's name is", dog.name, "He can eat. He is", dog.age, "Old")
return ""
}
func main(a) {
var animal Animal
dog := Dog{"dog".12}
animal = dog
animal.run()
animal.eat()
animal.fly()
}
Copy the code
The results of
Dog'Name is dog He can run. He is 12 years old.'s name is dog He can eat. He is 12Old Dog's name is dog He cannot fly.Because he is dog,dog cannot fly
Copy the code
Interface polymorphism
package main
import "fmt"
type Animal interface {
fly() string
}
// Define the structure
type Dog struct {
name string
age int
}
// Define the structure
type Bird struct {
name string
age int
}
// a function that takes an interface
func animalFly(animal Animal) {
animal.fly()
}
func (dog Dog) fly(a) string {
fmt.Println("Dog's name is", dog.name, "He cannot fly.Because he is dog,dog cannot fly ")
return ""
}
func (bird Bird) fly(a) string {
fmt.Println("Bird's name is", bird.name, "she can fly.Because he is bird,bird can fly ")
return ""
}
func main(a) {
dog := Dog{"dog".12}
bird := Bird{"bird".10}
animalFly(dog)
animalFly(bird)
}
Copy the code
The results of
Dog's name is dog He cannot fly.Because he is dog,dog cannot fly Bird's name is bird she can fly.Because he is bird,bird can fly
Copy the code
Embedding of interfaces
Go interfaces are very well supported for embedding. Interfaces can be embedded into other interfaces as if methods of the embedded interface were added directly to the interface.
type Dog interface {
run()
}
type Bird interface {
fly()
}
type Animal interface {
Dog
Bird
}
Copy the code
The above two cases are not difficult, you will basically understand the general operation of the interface.
Standard interface library in Go
- FMT. Stringer interface
Formatted print
// Stringer is implemented by any value that has a String method,
// which defines the ``native'' format for that value.
// The String method is used to print values passed as an operand
// to any format that accepts a string or to an unformatted printer
// such as Print.
type Stringer interface {
String() string
}
Copy the code
package main
import "fmt"
type Dog struct {
name string
age int
}
func (dog Dog)String(a)string {
return fmt.Sprintf("%s---%v",dog.name,dog.age)
}
func main(a) {
fmt.Println(Dog{"dog".12}) // dog---12
}
Copy the code
- Sort. Interface Interface
The sort. sort function of the Go language uses an Interface type sort.Interface to specify the convention between the common sorting algorithm and the types of sequences that can be sorted
package sort
type Interface interface {
Len() int
Less(i,j int) bool
Swap(i, j int)}Copy the code
This case from [go language Chinese — linkanyway] studygolang.com/articles/15…
package main
import (
"fmt"
"sort"
"time"
)
type Track struct {
Title string
Artist string
Album string
Year int
Length time.Duration
}
type Tracks []Track
func ParseDurationTime(s string) time.Duration {
d, err := time.ParseDuration(s)
iferr ! =nil {
return ParseDurationTime("0s")}else {
return d
}
}
// {{{ implementation of Sort interface
// Len is the number of elements in the collection.
func (x Tracks) Len(a) int {
return len(x)
}
// Less reports whether the element with
// index i should sort before the element with index j.
func (x Tracks) Less(i, j int) bool {
return x[i].Year < x[j].Year
}
// Swap swaps the elements with indexes i and j.
func (x Tracks) Swap(i, j int) {
x[i], x[j] = x[j], x[i]
}
// end implementation of Sort interface }}}
var tracks = Tracks{
{Title: "C#", Artist: "Delu", Album: "Reading", Year: 2017, Length: ParseDurationTime("3m38s")},
{Title: "Go", Artist: "Anderson", Album: "Reading", Year: 2018, Length: ParseDurationTime("3m38s")},
{Title: "Java Bible", Artist: "Js", Album: "Reading", Year: 2016, Length: ParseDurationTime("3m38s")}}
//main function
func main(a) {
sort.Sort(tracks)
for key, value := range tracks {
fmt.Printf("%v:%v \n", key, value)
}
}
Copy the code
The results of
0:{Java Bible Js Reading 2016 3m38s}
1:{C# Delu Reading 2017 3m38s}
2:{Go Anderson Reading 2018 3m38s}
Copy the code
- Errors. The error interface
Calling errors.New is very rare because there is a handy wrapper function, FMT.Errorf, which also handles string formatting
The easiest way to create an error is to call errors.New, which returns a New error based on the incoming error information. The entire Errors package is just four lines:
package errors
// New returns an error that formats as the given text.
// Each call to New returns a distinct error value even if the text is identical.
func New(text string) error {
return &errorString{text}
}
// errorString is a trivial implementation of error.
type errorString struct {
s string
}
func (e *errorString) Error(a) string {
return e.s
}
Copy the code
Type assertion in Go
Syntax for assertion types: x.(T), where x represents the type of an interface and T represents a type (or interface type). There are two possibilities
- First, if the type T of the assertion is a concrete type, then the type assertion checks whether x’s dynamic type is the same as T’s. If this check succeeds, the result of the type assertion is the dynamic value of X, which of course is of type T. In other words, a type assertion of a concrete type gets a concrete value from the object on which it operates. If the check fails, the next operation throws panic. Such as:
Example from — The Go Program Language
var w io.Writer
w = os.Stdout
f := w.(*os.File) // success f == os.Stdout
c := w.(*byte.Buffer) // panic: interface holds *os.File, not *bytes.Buffer
Copy the code
- Second, if the asserted type T is an interface type, the type assertion X.(T) checks whether the dynamic type of X satisfies the T interface. If this check succeeds, the dynamic type and dynamic value of the checked interface value remain unchanged, but the type of the interface value is converted to interface type T. In other words, a type assertion on an interface type changes the way the type is expressed, changes the set of methods available (usually larger), but it protects the dynamic type and value parts inside the interface value.
If the check fails, the next operation will throw panic unless two variables are used to receive the check result, such as f, OK := w.(IO.ReadWriter)
var w io.Writer
w = os.Stdout
rw := w.(io.ReadWriter) // success: *os.File has both Read and Write
w = new(ByteCounter)
rw = w.(io.ReadWriter) // panic: *ByteCounter has no Read method
Copy the code
Tip: If the asserted operation object X is a nil interface value, the type assertion will fail regardless of what type T is asserted.
package main
import (
"fmt"
)
/ / = = = = = = = = interface
type Tester interface {
getName() string
}
type Tester2 interface {
printName()
}
/ / = = = = = = = the Person type
type Person struct {
name string
}
func (p Person) getName(a) string {
return p.name
}
func (p Person) printName(a) {
fmt.Println(p.name)
}
/ / = = = = = = = = = = = =
func main(a) {
var t Tester
t = Person{"xiaohua"}
check(t)
}
func check(t Tester) {
// The first case
if f, ok1 := t.(Person); ok1 {
fmt.Printf("%T %s\n", f, f.getName())
}
// The second case
if t, ok2 := t.(Tester2); ok2 { // Reuse variable name t (no need to redeclare)
check2(t) // If the type assertion is true, the new t is converted to the Tester2 interface type, but its dynamic type and dynamic value remain unchanged}}func check2(t Tester2) {
t.printName()
}
Copy the code
The results of
main.Person xiaohua
xiaohua
Copy the code
—- those on TV slam the door and go not to lock the door because they basically don’t come back, so I never watch TV series, just look at the lines I can guess who died in a few episodes.