This is a creation in Article, where the information may have evolved or changed.
9. Notes go language-Methods and interfaces
Method
Go has no class. However, you can still define a method on a struct type.
The method recipient appears in a parameter between the Func keyword and the method name.
Package Main
Import (
"FMT"
"Math"
)
Type Vertex struct {
X, Yfloat64
}
Func (v *vertex) Abs () float64 {
Returnmath. SQRT (v.x*v.x + v.y*v.y)
}
Func Main () {
V: =&vertex{3, 4}
Fmt. Println (V.abs ())
}
Perform:
5
You can define any method for any type in the package, not just for the struct.
However, you cannot define a method on a type or an underlying type from another package.
Package Main
Import (
"FMT"
"Math"
)
Type Myfloat float64
Func (f myfloat) Abs () float64 {
If f< 0 {
Returnfloat64 (-F)
}
Returnfloat64 (f)
}
Func Main () {
F: =myfloat (-math. SQRT2)
Fmt. Println (F.abs ())
}
Execution Result:
1.4142135623730951
Method of the recipient as a pointer
Method can be associated with a pointer to a named type or a named type.
Just saw the two Abs method. One is on the *vertex pointer type and the other on the Myfloat value type. There are two reasons to use a pointer recipient. First, avoid copying values in each method call (more efficient if the value type is a large struct). Second, the method can modify the value that the receiver points to.
Try to modify the definition of Abs, while the scale method uses Vertex instead of *vertex as the receiver.
The scale method has no effect when V is Vertex. ' Scale ' modifies ' V '. When V is a value (not a pointer), the method sees a copy of Vertex and cannot modify the original value.
The way Abs works is the same. Just read ' V '. So it doesn't matter whether the original value (through the pointer) or the copy of the value is read.
Package Main
Import (
"FMT"
"Math"
)
Type Vertex struct {
X, Yfloat64
}
Func (v *vertex) scale (f float64) {
v.x =v.x * F
V.y =v.y * F
}
Func (v *vertex) Abs () float64 {
Returnmath. SQRT (v.x*v.x + v.y*v.y)
}
Func Main () {
V: =&vertex{3, 4}
V.scale (5)
Fmt. Println (V,v.abs ())
}
Perform:
&{1520} 25
Interface
An interface type is a collection defined by a set of methods.
The value of the interface type can hold any value that implements these methods.
Note: There is an error in the 22 line of the code. Because ABS is defined only on *vertex (pointer type), Vertex (value type) does not meet ' abser '.
Package Main
Import (
"FMT"
"Math"
)
Type Abser Interface {
Abs () float64
}
Func Main () {
var aabser
F: =myfloat (-math. SQRT2)
V: =vertex{3, 4}
a =f//a myfloat realized the Abser
a =&v//a *vertex realized the Abser
// the following line, v is a Vertex (rather than *vertex )
// so there's no implementation . Abser .
A = V
Fmt. Println (A.abs ())
}
Type Myfloat float64
Func (f myfloat) Abs () float64 {
If f< 0 {
Returnfloat64 (-F)
}
Returnfloat64 (f)
}
Type Vertex struct {
X, Yfloat64
}
Func (v *vertex) Abs () float64 {
Returnmath. SQRT (v.x*v.x + v.y*v.y)
}
#command-line-arguments
. \hello.go:22:cannot use V (type Vertex) as type Abser in assignment:
Vertexdoes not implement Abser (Abs method have pointer receiver)
Exitstatus 2
Implicitly-Interface
Types implement interfaces by implementing those methods. There is no need for explicit declaration, so there is no keyword "implements".
Implicit interfaces decouple the package that implements the interface and the package that defines the interface: non-dependent.
Therefore, there is no need to add a new interface name on each implementation, which also encourages explicit interface definitions.
Package IO defines Reader and ' Writer ', but not necessarily.
Package Main
Import (
"FMT"
"OS"
)
Type Reader Interface {
Read (B[]byte) (n int, err error)
}
Type Writer Interface {
Write (B[]byte) (n int, err error)
}
Type Readwriter Interface {
Reader
Writer
}
Func Main () {
var wwriter
//os. Stdout realized the Writer
W =os. Stdout
Fmt. fprintf (W, "Hello, writer\n")
}
Perform:
Hello,writer
Stringers
A ubiquitous interface is the Stringer defined in the FMT package.
Type Stringer struct {
String () string
}
Stringer is a type that can be used to describe itself as a string. The ' FMT ' package (and many other packages) uses this to output.
Package Main
Import "FMT"
Type person struct {
Namestring
Age int
}
Func (P person) string () string {
Returnfmt. Sprintf ("%v (%v years)", P.name, P.age)
}
Func Main () {
A: = person{"Arthurdent", 42}
Z: =person{"Zaphod Beeblebrox", 9001}
Fmt. Println (A,z)
}
Perform:
Arthurdent (years) Zaphod Beeblebrox (9001 years)
Error
The GO program uses the error value to indicate the status of the fault.
With FMT. Stringer similar, the ' error ' type is a built-in interface:
Type Error Interface {
Error () string
}
(with FMT.) Stringer similar, the ' FMT ' package will also attempt to match ' error ' on output. )
Normally the function returns an error value, and the code that invokes it should determine if the error equals ' nil ' to handle the error.
I, err: = StrConv. Atoi ("42")
If err! = Nil {
Fmt. Printf ("couldn ' t convert number:%v\n", err)
}
Fmt. Println ("Converted integer:", i)
The error is nil when it is successful, and non-nil errors indicate.
Package Main
Import (
"FMT"
"Time"
)
Type Myerror struct {
Whentime.time
Whatstring
}
Func (e *myerror) Error () string {
Returnfmt. Sprintf ("At%v,%s",
E.when,e.what)
}
Func run () error {
return&myerror{
Time. Now (),
"Itdidn ' t work",
}
}
Func Main () {
Iferr: = run (); Err! = Nil {
Fmt. PRINTLN (ERR)
}
}
Perform:
At2016-06-16 23:10:58.7118248 +0800 CST, it didn ' t work
Readers
IO package Specifies IO. Reader interface, which represents reading from the end of the data stream.
The Go standard library contains many implementations of this interface, including files, network connections, compression, encryption, and so on.
Io. The Reader interface has a Read method:
Func (T) Read (b []byte) (n int, err error)
Read populates the specified byte slice with data, and returns the number of bytes populated and the error information. Returns IO when the end of the data stream is encountered. EOF error.
The example code creates a strings. Reader. and reads its output at a rate of 8 bytes at a time.
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])
Iferr = = Io. EOF {
Break
}
}
}
Perform:
n= 8 Err = <nil> B = [72 101 108 108 111 44 32 82]
B[:n]= "Hello, R"
n= 6 err = <nil> B = [101 97 100 101 114 33 32 82]
b[:n]= "eader!"
n= 0 Err = EOF B = [101 97 100 101 114 33 32 82]
B[:n]= ""
Web Server
The package HTTP implements HTTP through any. The Handler value to respond to the HTTP request:
Package HTTP
Type Handler Interface {
Servehttp (w responsewriter, R *request)
}
In this example, the type Hello implements the ' HTTP '. Handler '.
Visit Http://localhost:4000/to see Greetings from the program.
Package Main
Import (
"FMT"
"Log"
"Net/http"
)
Type Hello struct{}
Func (H Hello) servehttp (
Whttp. Responsewriter,
R*http. Request) {
Fmt. Fprint (W, "hello!")
}
Func Main () {
var Hhello
err:= http. Listenandserve ("localhost:4000", h)
Iferr! = Nil {
Log. Fatal (ERR)
}
}
Image
Packageimage defines the Image interface:
Package image
Type Image Interface {
ColorModel () color. Model
Bounds () Rectangle
at (x, y int) color. Color
}
* Note *: The Rectangle return value of the ' Bounds ' method is actually an image. Rectangle, which is defined in the image package.
(See the documentation for full information.) )
Color. Color and color. The Model is also an interface, but usually because the predefined implementation image is used directly. RGBA and image. Rgbamodel and neglected. These interfaces and types are defined by the Image/color package.
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 ())
}
Perform:
(0,0)-(100,100)
00 0 0