11.9.md 6.5 KB

11.9 �սӿ�

11.9.1 ����

�սӿڻ�����С�ӿ��������κη���������ʵ�ֲ����κ�Ҫ��

type Any interface {}

�κ��������Ͷ�ʵ���˿սӿڣ����������� Java/C# �� Object �������ͣ���any �� Any �ǿսӿ�һ���ܺõı�������д��

�սӿ����� Java/C# ��������Ļ��ࣺ Object �࣬���ߵ�Ŀ��Ҳ�������

���Ը�һ���սӿ����͵ı��� var val interface {} ���κ����͵�ֵ��

ʾ�� 11.8 empty_interface.go��

package main
import "fmt"

var i = 5
var str = "ABC"

type Person struct {
	name string
	age  int
}

type Any interface{}

func main() {
	var val Any
	val = 5
	fmt.Printf("val has the value: %v\n", val)
	val = str
	fmt.Printf("val has the value: %v\n", val)
	pers1 := new(Person)
	pers1.name = "Rob Pike"
	pers1.age = 55
	val = pers1
	fmt.Printf("val has the value: %v\n", val)
	switch t := val.(type) {
	case int:
		fmt.Printf("Type int %T\n", t)
	case string:
		fmt.Printf("Type string %T\n", t)
	case bool:
		fmt.Printf("Type boolean %T\n", t)
	case *Person:
		fmt.Printf("Type pointer to Person %T\n", t)
	default:
		fmt.Printf("Unexpected type %T", t)
	}
}

�����

val has the value: 5
val has the value: ABC
val has the value: &{Rob Pike 55}
Type pointer to Person *main.Person

������������У��ӿڱ��� val �����θ���һ�� int��string �� Person ʵ����ֵ��Ȼ��ʹ�� type-swtich ����������ʵ�����͡�ÿ�� interface {} �������ڴ���ռ�������ֳ���һ�������洢�����������ͣ���һ�������洢�����������ݻ���ָ�����ݵ�ָ�롣

���� emptyint_switch.go ˵���˿սӿ��� type-swtich ������ lambda �������÷���

package main

import "fmt"

type specialString string

var whatIsThis specialString = "hello"

func TypeSwitch() {
	testFunc := func(any interface{}) {
		switch v := any.(type) {
		case bool:
			fmt.Printf("any %v is a bool type", v)
		case int:
			fmt.Printf("any %v is an int type", v)
		case float32:
			fmt.Printf("any %v is a float32 type", v)
		case string:
			fmt.Printf("any %v is a string type", v)
		case specialString:
			fmt.Printf("any %v is a special String!", v)
		default:
			fmt.Println("unknown type!")
		}
	}
	testFunc(whatIsThis)
}

func main() {
	TypeSwitch()
}

�����

any hello is a special String!

��ϰ 11.9 simple_interface3.go��

������ϰ11.2������������һ�� gI �����������ٽ��� Simpler ���͵IJ��������ǽ���һ���սӿڲ�����Ȼ��ͨ�����Ͷ����жϲ����Ƿ��� Simpler ���͡������ main ʹ�� gI ȡ�� fI ��������������ȷ����Ĵ����㹻��ȫ��

11.9.2 ����ͨ�����ͻ������ͬ���ͱ���������

�� 7.6.6 �����ǿ������ܱ������������ int ���顢float �����Լ� string ���飬��ô�����������͵������أ��Dz������DZ�����Լ����ʵ�����ǣ�

��������֪������ô���ˣ�����ͨ��ʹ�ÿսӿڡ������Ǹ��սӿڶ�һ���������� Element��type Element interface{}

Ȼ����һ���������͵Ľṹ�� Vector��������һ�� Element ����Ԫ�ص���Ƭ��

type Vector struct {
	a []Element
}

Vector ���ܷ��κ����͵ı�������Ϊ�κ����Ͷ�ʵ���˿սӿڣ�ʵ���� Vector ��ŵ�ÿ��Ԫ�ؿ����Dz�ͬ���͵ı���������Ϊ������һ�� At() �������ڷ��ص� i ��Ԫ�أ�

func (p *Vector) At(i int) Element {
	return p.a[i]
}

�ٶ�һ�� Set() �����������õ� i ��Ԫ�ص�ֵ��

func (p *Vector) Set(i int, e Element) {
	p.a[i] = e
}

Vector �д洢������Ԫ�ض��� Element ���ͣ�Ҫ�õ����ǵ�ԭʼ���ͣ�unboxing�����䣩��Ҫ�õ����Ͷ��ԡ�TODO��The compiler rejects assertions guaranteed to fail�����Ͷ�������������ʱ��ִ�У���������������ʱ����

��ϰ 11.10 min_interface.go / minmain.go��

����11.7�п����� Sorter �ӿڣ�����һ�� Miner �ӿڲ�ʵ��һЩ��Ҫ�IJ��������� Min ����һ�� Miner ���ͱ����ļ��ϣ�Ȼ����㲢���ؼ�������С��Ԫ�ء�

11.9.3 ����������Ƭ���սӿ���Ƭ

��������һ�� myType ���͵�������Ƭ�����뽫��Ƭ�е����ݸ��Ƶ�һ���սӿ���Ƭ�У����ƣ�

var dataSlice []myType = FuncReturnSlice()
var interfaceSlice []interface{} = dataSlice

��ϧ������ô��������ʱ�������cannot use dataSlice (type []myType) as type []interface { } in assignment

ԭ�������������ڴ��еIJ����Dz�һ���ģ��ο�http://golang.org/doc/go_spec.html����

����ʹ�� for-range �����һ��һ����ʽ�ظ��ƣ�

var dataSlice []myType = FuncReturnSlice()
var interfaceSlice []interface{} = make([]interface{}, len(dataSlice))
for ix, d := range dataSlice {
    interfaceSlice[i] = d
}

11.9.4 ͨ�����͵Ľڵ����ݽṹ

��10.1�����������������б��������������ݽṹ�������ǵĶ�����ʹ����һ�ֽнڵ�ĵݹ�ṹ�����ͣ��ڵ����һ��ij�����͵������ֶΡ����ڿ���ʹ�ÿսӿ���Ϊ�����ֶε����ͣ��������Ǿ���д��ͨ�õĴ��롣������ʵ��һ���������IJ��ִ��룺ͨ�ö��塢���ڴ����սڵ�� NewNode ���������������ݵ� SetData ����.

ʾ�� 11.10 node_structures.go:

package main

import "fmt"

type Node struct {
	le   *Node
	data interface{}
	ri   *Node
}

func NewNode(left, right *Node) *Node {
	return &Node{left, nil, right}
}

func (n *Node) SetData(data interface{}) {
	n.data = data
}

func main() {
	root := NewNode(nil, nil)
	root.SetData("root node")
	// make child (leaf) nodes:
	a := NewNode(nil, nil)
	a.SetData("left node")
	b := NewNode(nil, nil)
	b.SetData("right node")
	root.le = a
	root.ri = b
	fmt.Printf("%v\n", root) // Output: &{0x125275f0 root node 0x125275e0}
}

11.9.5 �ӿڵ��ӿ�

һ���ӿڵ�ֵ���Ը�ֵ����һ���ӿڱ�����ֻҪ�ײ�����ʵ���˱�Ҫ�ķ��������ת����������ʱ���м��ģ�ת��ʧ�ܻᵼ��һ������ʱ�������� 'Go' ���Զ�̬��һ�棬���������� Ruby �� Python ��Щ��̬������Ƚϡ�

�ٶ���

var ai AbsInterface // declares method Abs()
type SqrInterface interface {
    Sqr() float
}
var si SqrInterface
pp := new(Point) // say *Point implements Abs, Sqr
var empty interface{}

��ô������������Ͷ����ǺϷ��ģ�

empty = pp                // everything satisfies empty
ai = empty.(AbsInterface) // underlying value pp implements Abs()
// (runtime failure otherwise)
si = ai.(SqrInterface) // *Point has Sqr() even though AbsInterface doesn��t
empty = si             // *Point implements empty set
// Note: statically checkable so type assertion not necessary.

�����Ǻ������õ�һ�����ӣ�

type myPrintInterface interface {
	print()
}

func f3(x myInterface) {
	x.(myPrintInterface).print() // type assertion to myPrintInterface
}

x ת��Ϊ myPrintInterface ��������ȫ��̬�ģ�ֻҪ x �ĵײ����ͣ���̬���ͣ������� print ����������þͿ����������С�