zoukankan      html  css  js  c++  java
  • goang Receiver & interface

    package main
    
    import (
        "fmt"
    )
    
    type Pointer struct {
        x string
    }
    
    func (this *Pointer) PrintX() {
        fmt.Printf("X:%s
    ", this.x)
    }
    
    func (this *Pointer) SetX(str string) {
        this.x = str 
    }
    
    type Value struct {
        x string
    }
    
    func (this Value) PrintX() {
        fmt.Printf("X:%s
    ", this.x)
    }
    
    func (this Value) SetX(str string) {
        this.x = str 
    }
    
    func main() {
        p1 := Pointer{x: "Pointer"}
        p1.PrintX()
        p1.SetX("Pointer1")
        p1.PrintX()
    
        p2 := &Pointer{}
        p2.PrintX()
        p2.SetX("Pointer2")
        p2.PrintX()
    
        p3 := Value{x: "Value"}
        p3.PrintX()
        p3.SetX("Value1")
        p3.PrintX()
    
        p4 := &Value{x: "value"}
        p4.PrintX()
        p4.SetX("Value2")
        p4.PrintX()
    }

    运行结果:

    X:Pointer
    X:Pointer1
    X:
    X:Pointer2
    X:Value
    X:Value
    X:value
    X:value

    说明:1 无论是T*作为receiver还是T类型作为接受者,都可以用实例、或者实例的指针调用函数,但是T*作为接受者将改变receiver的内容,而T类型改变的是副本,原始对象不会改变。

    type Type struct {
    }
    
    type PType struct {
    }
    
    type Inter interface {
        post()
    }
    
    // 接收者非指针
    func (t Type) post() {
    }
    
    // 接收者是指针
    func (t *PType) post() {
    }
    
    func test() {
        var it Inter
        //var it *Inter //接口不能定义为指针
        pty := &Type{}
        it = ty   // 将变量赋值给接口,OK
        it.post() // 接口调用方法,OK, receiver 是T
    
        ty := Type{}
        it = pty  // 把指针变量赋值给接口,OK
        it.post() // 接口调用方法,OK, receiver 是T
    
        pty2 := &PType{}
        it = pty2 // 把指针变量赋值给接口,OK
        it.post() // 接口调用方法,OK, receiver 是*T
    
        //ty2 := PType{}
        //it = ty2  // 将变量赋值给接口,error
        //it.post() // 接口调用方法,error, receiver 必须是T,而不能是T
    }

    详细代码:http://play.golang.org/p/KG8-Qb7gqM

    为什么编译器不考虑我们的值是实现该接口的类型?接口的调用规则是建立在这些方法的接受者和接口如何被调用的基础上。下面的是语言规范里定义的规则,这些规则用来说明是否我们一个类型的值或者指针实现了该接口:

    • 类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集

    这条规则说的是如果我们用来调用特定接口方法的接口变量是一个指针类型,那么方法的接受者可以是值类型也可以是指针类型。显然我们的例子不符合该规则,因为我们传入 SendNotification 函数的接口变量是一个值类型。

    • 类型 T 的可调用方法集包含接受者为 T 的所有方法

    这条规则说的是如果我们用来调用特定接口方法的接口变量是一个值类型,那么方法的接受者必须也是值类型该方法才可以被调用。显然我们的例子也不符合这条规则,因为我们 Notify 方法的接受者是一个指针类型。

    语言规范里只有这两条规则,我通过这两条规则得出了符合我们例子的规则:

    • 类型 T 的可调用方法集不包含接受者为 *T 的方法

    Interface也是引用类型。

     

     

     

  • 相关阅读:
    ubuntu安装Elasticsearch
    PHP如何计算脚本执行时间
    MVC+EF中返回JSON的性能和安全问题
    博客园最新的一个模板样式有问题
    Entity Framework 批量插入很慢吗?我自己测试下
    用 Raphaël 绘制中国地图 + 显示数据
    博客园的手机版(非官方) MVC+jQuery.Mobile
    BitCovert,与移位,加法性能比较
    探讨微软ASP.NET AJAX控件开发技术(客户端)
    (十三)树【C++刷题】
  • 原文地址:https://www.cnblogs.com/diegodu/p/5139571.html
Copyright © 2011-2022 走看看