zoukankan      html  css  js  c++  java
  • 9.interface

    method set

    // Method Sets
    // Sample program to show how to understand method sets.
    package main
    
    import "fmt"
    
    // notifier is an interface that defines notification notifier是定义通知的接口。
    // type behavior. 类型的行为。
    
    type notifier interface {
    	notify()
    }
    
    // user defines a user in the program.
    type user struct {
    	name  string
    	email string
    }
    
    // notify implements the notifier interface with a pointer receiver. 通知用一个指针接收器实现notifier接口。
    func (u *user) notifier() {
    	fmt.Printf("Sending User Email To %s<%s>
    ",
    		u.name,
    		u.email)
    }
    
    func main() {
    	// Create a value of type User and send a notification. 创建类型用户的值并发送通知。
    	u := user{"Bill", "bill@email.com"}
    
    	// Values of type user do not implement the interface because pointer
    	// receivers don't belong to the method set of a value.
    	// 类型用户的值不实现该接口,因为指针。
    	// 接收器不属于值的方法集。
    	sendNotification(u)
    
    	// ./example1.go:36: cannot use u (type user) as type notifier in argument to sendNotification:
    	//   user does not implement notifier (notify method has pointer receiver)
    
    	// /例二。go:36:不能使用u(类型用户)作为类型通知者在参数中发送通知:
    	//用户不实现通知器(通知方法有指针接收器)
    
    }
    
    // sendNotification accepts values that implement the notifier
    // interface and sends notifications.
    // sendNotification接受实现通知的值。
    // 接口和发送通知。
    func sendNotification(n notifier) {
    	n.notify()
    }
    
    
    package main
    
    import "fmt"
    
    // Sample program to show how polymorphic behavior with interfaces.
    // 示例程序演示多态行为与接口的关系。
    
    // reader is an interface that defines the act of reading data. 阅读器是定义读取数据行为的接口。
    type reader interface {
    	read(b []byte) (int, error)
    }
    
    // file defines a system file.
    type file struct {
    	name string
    }
    
    // read implements the reader interface for a file. // read实现文件的读取器接口。
    func (file) read(b []byte) (int, error) {
    	s := "<rss><channel><title>Going Go Programming</title></channel></rss>"
    	copy(b, s)
    	return len(s), nil
    }
    
    // pipe defines a named pipe network connection. 管道定义了一个指定的管道网络连接。
    type pipe struct {
    	name string
    }
    
    // read implements the reader interface for a network connection. read实现了网络连接的读取器接口
    func (pipe) read(b []byte) (int, error) {
    	s := `{name: "bill", title: "developer"}`
    	copy(b, s)
    	return len(s), nil
    }
    func main() {
    	// Create two values one of type file and one of type pipe. 创建两个值一个类型文件和一个类型管道。
    	f := file{"data.json"}
    	p := pipe{"cfg_service"}
    
    	// Call the retrieve function for each concrete type. 为每个具体类型调用检索函数。
    	retrieve(f)
    	retrieve(p)
    }
    
    // retrieve can read any device and process the data. 检索可以读取任何设备并处理数据。
    func retrieve(r reader) error {
    	data := make([]byte, 100)
    	len_, err := r.read(data)
    	if err != nil {
    		return err
    	}
    
    	fmt.Println(string(data[:len_]))
    	return nil
    }
    
    

    Address Of Value

    // Sample program to show how you can't always get the address of a value.
    //示例程序,以显示您不能总是得到一个值的地址。
    package main
    
    import "fmt"
    
    // duration is a named type with a base type of int. // duration是一个命名类型,有一个基本类型的int类型。
    type duration int
    
    // notify implements the notifier interface. 通知实现notifier接口。
    func (d *duration) notify() {
    	fmt.Println("Sending Notification in", *d)
    }
    func main() {
    	duration(42).notify()
    
    	// ./example3.go:18: cannot call pointer method on duration(42)
    	// ./example3.go:18: cannot take the address of duration(42)
    }
    
    

    Storage By Value

    // Sample program to show how the concrete value assigned to
    // the interface is what is stored inside the interface.
    // 示例程序演示如何分配具体的值。
    // 接口是存储在接口中的内容。
    package main
    
    import "fmt"
    
    // printer displays information. 打印机显示信息。
    type printer interface {
    	print()
    }
    
    // user defines a user in the program. 用户在程序中定义用户。
    type user struct {
    	name string
    }
    
    // print displays the user's name. 打印显示用户的名字。
    func (u user) print() {
    	fmt.Printf("User Name: %s
    ", u.name)
    }
    
    func main() {
    	// Create values of type user and admin.
    	u := user{"Bill"}
    
    	// Add the values and pointers to the slice of
    	// printer interface values.
    	entities := []printer{
    
    		// Store a copy of the user value in the interface value.
    		u,
    
    		// Store a copy of the address of the user value in the interface value.
    		&u,
    	}
    
    	// Change the name field on the user value.
    	u.name = "Bill_CHG"
    
    	// Iterate over the slice of entities and call
    	// print against the copied interface value.
    	for _, e := range entities {
    		e.print()
    	}
    
    	// When we store a value, the interface value has its own
    	// copy of the value. Changes to the original value will
    	// not be seen.
    
    	// When we store a pointer, the interface value has its own
    	// copy of the address. Changes to the original value will
    	// be seen.
    
    	//当我们存储一个值时,接口值有它自己的值。
    	//价值的副本。更改原始值将。
    	// 不是。
    
    	//当我们存储一个指针时,接口值有它自己的值。
    	//地址的副本。更改原始值将。
    
    	/*
    		User Name: Bill
    		User Name: Bill_CHG
    	*/
    
    }
    
    
    // Sample program that explores how interface assignments work when
    // values are stored inside the interface.
    // 示例程序,探索接口分配如何工作。
    // 值存储在接口中。
    
    package main
    
    import (
    	"fmt"
    	"unsafe"
    )
    
    // notifier provides support for notifying events. notifier为通知事件提供支持。
    type notifier interface {
    	notify()
    }
    
    // user represents a user in the system.
    type user struct {
    	name string
    }
    
    // notify implements the notifier interface.
    func (u user) notify() {
    	fmt.Println("Alert", u.name)
    }
    
    func inspect(n *notifier, u *user) {
    	word := uintptr(unsafe.Pointer(n)) + uintptr(unsafe.Sizeof(&u))
    	value := (**user)(unsafe.Pointer(word))
    	fmt.Printf("Addr User: %p  Word Value: %p  Ptr Value: %v
    ", u, *value, **value)
    }
    
    func main() {
    
    	// Create a notifier interface and concrete type value. 创建一个通知接口和具体类型值。
    	var n1 notifier
    	u := user{"bill"}
    
    	// Store a copy of the user value inside the notifier
    	// interface value. 在notifier接口值中存储用户值的副本。
    	n1 = u
    
    	// We see the interface has its own copy. 我们看到这个接口有它自己的副本。
    	// Addr User: 0x1040a120  Word Value: 0x10427f70  Ptr Value: {bill}
    	inspect(&n1, &u)
    
    	// Make a copy of the interface value.
    	n2 := n1
    
    	// We see the interface is sharing the same value stored in
    	// the n1 interface value.
    	// Addr User: 0x1040a120  Word Value: 0x10427f70  Ptr Value: {bill}
    	inspect(&n2, &u)
    
    	// Store a copy of the user address value inside the
    	// notifier interface value.
    	n1 = &u
    
    	// We see the interface is sharing the u variables value
    	// directly. There is no copy.
    	// Addr User: 0x1040a120  Word Value: 0x1040a120  Ptr Value: {bill}
    	inspect(&n1, &u)
    }
    
    /*
    Addr User: 0xc042008230  Word Value: 0xc04202bf68  Ptr Value: {bill}
    Addr User: 0xc042008230  Word Value: 0xc04202bf68  Ptr Value: {bill}
    Addr User: 0xc042008230  Word Value: 0xc042008230  Ptr Value: {bill}
    */
    
    

    练习

    // Declare an interface named speaker with a method named speak. Declare a struct
    // named english that represents a person who speaks english and declare a struct named
    // chinese for someone who speaks chinese. Implement the speaker interface for each
    // struct using a value receiver and these literal strings "Hello World" and "你好世界".
    // Declare a variable of type speaker and assign the address of a value of type english
    // and call the method. Do it again for a value of type chinese.
    //使用名为speak的方法声明一个名为speaker的接口。声明一个结构体
    //英文名,代表一个会说英语的人,并宣布一个结构名称。
    //中国人说汉语。为每个用户实现speaker接口。
    //结构体使用价值接收机和这些字符串“Hello World”和“你好世界”。
    //声明一个类型的扬声器的变量,并分配一个英语的值的地址。
    //并调用该方法。再做一遍,看看中文的价值。
    
    // Add a new function named sayHello that accepts a value of type speaker.
    // Implement that function to call the speak method on the interface value. Then create
    // new values of each type and use the function.
    //添加一个名为sayHello的新函数,该函数接受类型speaker的值。
    //实现该函数调用接口值上的speak方法。然后创建
    //每种类型的新值并使用该函数。
    package main
    
    import "fmt"
    
    // speaker implements the voice of anyone.
    type speaker interface {
    	speak()
    }
    
    // english represents an english speaking person.
    type english struct{}
    
    // speak implements the speaker interface using a
    // value receiver.
    func (english) speak() {
    	fmt.Println("Hello World")
    }
    
    // chinese represents a chinese speaking person.
    type chinese struct{}
    
    // speak implements the speaker interface using a
    // pointer receiver.
    func (*chinese) speak() {
    	fmt.Println("你好世界")
    }
    
    func main() {
    
    	// Declare a variable of the interface speaker type 声明一个接口扬声器类型的变量。
    	// set to its zero value.
    	var sp speaker
    
    	// Declare a variable of type english.
    	var e english
    
    	// Assign the english value to the speaker variable. 将英语值分配给speaker变量。
    	sp = e
    	// Call the speak method against the speaker variable.
    	sp.speak()
    
    	// Declare a variable of type chinese.
    	var c chinese
    
    	// Assign the chinese pointer to the speaker variable. 将中文指针指定给speaker变量。
    	sp = &c
    
    	// Call the speak method against the speaker variable.
    	sp.speak()
    	fmt.Println("============
    ")
    
    	// Call the sayHello function with new values and pointers
    	// of english and chinese.
    
    	sayHello(english{})
    	sayHello(&english{})
    	sayHello(&chinese{})
    
    }
    
    // sayHello abstracts speaking functionality. sayHello抽象说话的功能。
    func sayHello(sp speaker) {
    	sp.speak()
    }
    
    /*
    Hello World
    你好世界
    ============
    
    Hello World
    Hello World
    你好世界
    */
    
    
  • 相关阅读:
    洛咕11月月赛部分题解 By cellur925
    POJ 2411 Mondriaan's Dream 【状压Dp】 By cellur925
    Luogu P1637 三元上升子序列【权值线段树】By cellur925
    Luogu P1438无聊的序列【线段树/差分】By cellur925
    Luogu P1558 色板游戏【线段树/状态压缩】By cellur925
    Luogu P4403 [BJWC2008]秦腾与教学评估【二分答案】By cellur925
    Luogu P3941 入阵曲【前缀和】By cellur925
    查询事件状态,mysql查看事件是否开启,设置启动时自动开启方法
    Logback详细整理,基于springboot的日志配置
    使用release自动打包发布正式版详细教程
  • 原文地址:https://www.cnblogs.com/zrdpy/p/8591398.html
Copyright © 2011-2022 走看看