切片

1、对一个切片进行切片时,可以使用第三个索引来限制切片的长度,这样就可以保证对新切片进行append时不会修改原切片的内容。

    source := []string{"a", "b", "c", "d", "e"}
    slice := source[2:3:3]
    slice = append(slice, "f")
    fmt.Println(source)
    fmt.Println(slice)
    
   //Output:
   //[a b c d e]
    //[c f]

接口

1、方法集

先看一下问题:

type notifier interface {
    notify()
}

type user struct {
    name, email string
}

func (u *user) notify() {
    fmt.Printf("sending eamil to %s<%s>", u.name, u.email)
}

func sendNotification(n notifier) {
    n.notify()
}

func main() {
    u := user{"zshanjun", "zshanjun@kkk.com"}
    sendNotification(u)
}

// go build
// cannot use u (type user) as type notifier in argument to sendNotification:
//        user does not implement notifier (notify method has pointer receiver)

原因:
编译不通过的原因是user类型的值并没有实现这个接口

规则:
要了解用指针接收者来实现接口时为什么user类型的值无法实现改接口,需要先了解方法集。
方法集定义了一组关联到给定类型的值或者指针的方法。定义方法时使用的接收者的类型决定了这个方法是关联到值,还是关联到指针,还是两个都关联。

Method Receivers            Values
---------------------------------------
(t T)                             T and *T
(t *T)                             *T

深层次原因:
现在的问题是,为什么有这种限制?事实上,编译器并不是总能自动获取到一个值的地址,例子如下:

type duration int

func (d *duration) pretty() string {
    return fmt.Sprintf("Duration: %d", *d)
}

func main() {
    duration(42).pretty()
}

//cannot call pointer method on duration(42)
//cannot take the address of duration(42)

公开或未公开的标识符

1、返回未公开的标识符

// counter 包
package counter

type alertCount int

func New(value int) alertCount {
    return alertCount(value)
}


// main 程序入口
func main(){
    counter :=     counter.New(10)
    
    fmt.Println(counter)
}

要让上面的行为可写,需要两个理由。
第一,公开或未公开的标识符,不是一个值。
第二,短变量声明操作符,有能力捕获引用的类型,并创建一个未公开的类型的变量。永远不能显式创建一个未公开的变量,不过短变量声明操作符可以这么做。



登陆发表评论