Why are interfaces needed in Golang?

后端 未结 6 1749
臣服心动
臣服心动 2020-11-29 19:44

In Golang, we use structs with receiver methods. everything is perfect up to here.
I\'m not sure what interfaces are, however. We define methods in structs and if we wan

6条回答
  •  既然无缘
    2020-11-29 19:48

    I will show here, two interesting use cases of interfaces in Go:

    1- See these two simple interfaces:

    type Reader interface {
        Read(p []byte) (n int, err error)
    }
    
    type Writer interface {
        Write(p []byte) (n int, err error)
    }
    

    Using these two simple interfaces you may do this interesting magic:

    package main
    
    import (
        "bufio"
        "bytes"
        "fmt"
        "io"
        "os"
        "strings"
    )
    
    func main() {
        file, err := os.Create("log.txt")
        if err != nil {
            panic(err)
        }
        defer file.Close()
    
        w := io.MultiWriter(file, os.Stdout)
        r := strings.NewReader("You'll see this string twice!!\n")
        io.Copy(w, r)
    
        slice := []byte{33, 34, 35, 36, 37, 38, 39, 10, 13}
        io.Copy(w, bytes.NewReader(slice)) // !"#$%&'
    
        buf := &bytes.Buffer{}
        io.Copy(buf, bytes.NewReader(slice))
        fmt.Println(buf.Bytes()) // [33 34 35 36 37 38 39 10 13]
    
        _, err = file.Seek(0, 0)
        if err != nil {
            panic(err)
        }
    
        r = strings.NewReader("Hello\nWorld\nThis\nis\nVery\nnice\nInterfacing.\n")
        rdr := io.MultiReader(r, file)
        scanner := bufio.NewScanner(rdr)
        for scanner.Scan() {
            fmt.Println(scanner.Text())
        }
    }
    

    Output:

    You'll see this string twice!!
    !"#$%&'
    
    [33 34 35 36 37 38 39 10 13]
    Hello
    World
    This
    is
    Very
    nice
    Interfacing.
    You'll see this string twice!!
    !"#$%&'
    

    I hope this code is clear enough:
    reads from string using strings.NewReader and writes concurrently to both file and os.Stdout using io.MultiWriter with just io.Copy(w, r). Then reads from slice using bytes.NewReader(slice) and writes concurrently to both file and os.Stdout. Then copy slice to the buffer io.Copy(buf, bytes.NewReader(slice)) then goto the file origin using file.Seek(0, 0) then first read from string using strings.NewReader then continue reading that file using io.MultiReader(r, file) and bufio.NewScanner and Print all of then using fmt.Println(scanner.Text()).


    2- And this is another interesting use of interface:

    package main
    
    import "fmt"
    
    func main() {
        i := show()
        fmt.Println(i) // 0
    
        i = show(1, 2, "AB", 'c', 'd', []int{1, 2, 3}, [...]int{1, 2})
        fmt.Println(i) // 7
    
    }
    func show(a ...interface{}) (count int) {
        for _, b := range a {
            if v, ok := b.(int); ok {
                fmt.Println("int: ", v)
            }
        }
        return len(a)
    }
    

    output:

    0
    int:  1
    int:  2
    7
    

    And nice example to see: Explain Type Assertions in Go

    Also see: Go: What's the meaning of interface{}?

提交回复
热议问题