您的位置:首页 > 编程语言 > Go语言

go语言学习笔记-接口学习

2017-05-13 21:53 781 查看

Interface概述

package main

import (
"fmt"
"bufio"
)

/*
io下write接口的定义
type Writer interface {
Write(p[]byte) (int, error)
}

os.Stdout变量的定义为一个*os.File类型
Stdout = NewFile(uintptr(syscall.Stdout), "/dev/stdout")

*byte.Buffer类型中实现了writer\reader接口
*/
type ByteCount int

//实现接口io.Writer
func (c *ByteCount) Write(p []byte) (int, error) {
*c += ByteCount(len(p))
return len(p), nil
}

func main() {
var c ByteCount = 0
var name = "neojos"
fmt.Fprintf(&c, "hello, %s", name)
fmt.Println(c)

var line []byte = []byte("good night neojos!")
for start, width := 0, 0; start < len(line); start += width {
advance, token, error := bufio.ScanWords(line[width:], true)
fmt.Printf("%d, %s, %v\n", advance, string(token), error)
width += advance
}
}


接口约定

package main

import (
"io"
"strings"
"bytes"
"fmt"
)

/*
在声明方法的时候,类型声明为指针和值需要明确的地方:
1. 虽然方法声明为了指针类型,但是通过值类型参数仍然可以调用.但这其实是编译器帮我们做了
处理,自动获取的变量的指针地址
type IntSet struct {
}
func (i *IntSet) String() string {
}

var is IntSet
is.String()

2. 还需要注意:变量和临时变量是有区别的,比如下面这样是会编译错误的。因为编译器获取不到临时变量的地址
IntSet{}.String()

3. 在接口实现的时候会明确区分值类型和指针类型,比如,下面是编译不通过的,is是值类型:
var _ fmt.Stringer = is

查看strings.NewReader实现Reader接口
type Reader struct {
s   string
i   int64
prevRune    int
}

func (r *Reader) Read(b []byte) (n int, err error) {
if r.i > int64(len(r.s)) {
return 0, io.EOF
}
r.prevRune = -1
n = copy(b, r.s[r.i:])
r.i += int64(n)
return
}
*/

func main() {
var sr = strings.NewReader("hello")
var r io.Reader = sr

var rep = []byte("he*** neojos!")
r.Read(rep)

var w = bytes.Buffer{}
sr.WriteTo(&w)

fmt.Printf("%s\n", rep)
fmt.Fprintf(&w, "%s", rep)
fmt.Println(w.String())
}


断言Switch语法

//go语言中interface的两种存在形式
//1. 提供函数的调用,比如io.Reader
//2. 作为一种值类型,包装其他不同类型的值
//因为interface作为值类型,没有任何的方法可以调用,所以出现了断言。x.(assert type)
package main

import (
"fmt"
)

//
func sqlQuote(x interface{}) string {
if x == nil {
return "NULL"
} else if _, ok := x.(int); ok {
return fmt.Sprintf("%d", x)
} else if _, ok := x.(uint); ok {
return fmt.Sprintf("%d", x)
} else if _, ok := x.(string); ok {
return fmt.Sprintf("%s", x)
} else if b, ok := x.(bool); ok {
if b {
return "TRUE"
}
return "FALSE"
} else {
panic(fmt.Sprintf("unexcepted type %T:%v", x, x))
}
}

//方法中x转换成了不同作用域中的同名变量先
func sqlQuoteSwitch(x interface{}) string {
switch x := x.(type) {
case nil:
return "NULL"
case int, uint:
return fmt.Sprintf("%d", x)
case bool :
if x {
return "TRUE"
}
return "FALSE"
case string:
return fmt.Sprintf("%s", x)
default:
panic(fmt.Sprintf("unexcepted type %T:%v", x, x))
}
}

func main() {
var a interface{} = string("http://baby.360.cn")
fmt.Println(sqlQuote(a))

var x interface{} = bool(false)
fmt.Println(sqlQuoteSwitch(x))
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  学习GO语言