Golang interface and three dots(...)

  1. ... (three dots)
  2. interface
  3. interface and three dots
  4. 引数が interface
  5. struct を interface で受取る
  6. コンポジション (承継)
  7. 関数を変数に代入
  8. 引数に関数を取る
  9. Interface example
  10. type example

  1. ... (three dots)
  2. A: ワイルドカード的な使用
    	go get -u -f -t ./...
    	   "./..."は現在のディレクトリ("./")以下すべて("...")のパッケージ
    	   
    	go build ./...
    	go install ./...
    
    B: 変数の個数
    	s1 := []string { "test1", "test2" }     
    	s2 := [...]string { "test1", "test2" }  // [2]string{ "test1", "test2" } と同じ
    	
    	f1 := reflect.TypeOf(s1)
    	f2 := reflect.TypeOf(s2)
    	fmt.Println("s1:", f1.Kind()) // slice 
    	fmt.Println("s2:", f2.Kind()) // array
    
    C: 可変長引数 (Variadic)
    	x := []int{1,2,3}
    	y := []int{4,5,6}
    	x = append(x, y...) // slice の結合
    	 // x = {1,2,3,4,5,6}
    
    	nums := []int{10, 20, 30}
    	adder(nums...)
    	adder(1,2,3,4)
    	
    	func adder(args ...int) int {
    		total := 0
    		for _, v := range args {
    			total += v
    		}
    		return total
    	}
    
  3. interface
  4. A: 変数の型
    	map[string]interface{}
    	map[interface{}]interface{}
    	
    	t1 := map[string]interface{}{     "aa": 11,"bb":"BB"}	
    	t2 := map[interface{}]interface{}{"aa": 11, 22: "BB"}	
    	
    B: 引数の型
    	func tt1(dat interface{}){ }
    	func tt2(dat map[string]interface{}){ }
    	  
    C:抽象関数の定義
    	ポリモーフィズム(Polymorphism)
    	
    	type T interface{
    		funcA(int) error
    		funcB(string) (string,error)
    	}
    
  5. interface and three dots
  6. A: 引数が interface
    	tt("args", 1, "aa", "bb", 12.345)
    
    	func tt(args string, dat ... interface{}){
    		for _,v := range dat{ 
    			switch v.(type) {
    				case string:
    					fmt.Printf("string:%s\n", v.(string))
    				case int: 
    					fmt.Printf("int:%d\n", v.(int) )
    				case float64: 
    					fmt.Printf("float64:%f\n", v.(float64) )
    				default:
    					fmt.Println("default:", v)
    			}
    		}
    	}
    	
    B: 引数が struct
    	type T struct{
    		Key  string
    		Val  interface{}
    	 }
    
    	t1 := &T{Key:"aa",Val: 11}
    	t2 := &T{Key:"bb",Val: "test"}
    	tt("args",t1,t2)
    	
    	func tt(args string, dat ... *T){
    		for _,v := range dat{ 
    			switch v.Val.(type) {
    				case string:
    					fmt.Printf("string:%s:%s\n",v.Key, v.Val.(string))
    				case int: 
    					fmt.Printf("int:%s:%d\n", v.Key,v.Val.(int) )
    				case float64: 
    					fmt.Printf("float64:%s:%f\n", v.Key,v.Val.(float64) )
    				default:
    					fmt.Println("default:",v.Key,v.Val)		
    			}
    		}
    	}	
    
  7. 引数が interface
  8. A:  map[string]interface{} を map[string]interface{} で受取る
    	t1 := map[string]interface{}{"aa": 11, "bb": "BB"}	
    	tt(t1)
    	
    	func tt(dat map[string]interface{}){
    		c2 := map[string]string{}
    		for k,v := range dat{ 
    			switch v.(type) {
    				case string:
    					c2[k] = v.(string)
    				case int: 
    					c2[k] = fmt.Sprint(v) // v.(int)
    				case float64: 
    					 c2[k] = fmt.Sprint(v) // v.(float64)
    				default:
    					fmt.Println("default:",v)
    			}
    		}
    		fmt.Printf("dat::%v\n", c2)
    	}
    	
    B:  map[string]interface{} を interface{} で受取る
    	t1 := map[string]interface{}{"aa": 11, "bb": "BB"}	
    	tt(t1)
    	
    	func tt(dat interface{}){
    		c2 := map[string]string{}
    		for k, v := range dat.(map[string]interface{}) {	
    			switch v.(type) {
    				case string:
    					c2[k] = v.(string)
    				case int:
    					c2[k] = fmt.Sprint(v) // v.(int)
    				case float64:
    					c2[k] = fmt.Sprint(v) // v.(float64)
    				case bool:
    					c2[k] = fmt.Sprint(v) // v.(bool) 
    				case nil:
    					c2[k] = ""
    				case []string:
    					c2[k] = strings.Join(v.([]string), ",") 
    					
    				default:
    					fmt.Println("default:", k,v)
    			}
    		}
    		fmt.Printf("dat::%v\n", c2)
    	}
    
  9. struct を interface で受取る
  10. type TT struct{
    	aa string
    	bb int
    	cc int
    }	
    
    A: struct に変換する
    	t3 := &TT{aa: "test", bb: 11, cc: 1234}
    	tt("TT",t3)
    		
    	func tt(arg string, dat interface{}){	
    		if arg == "TT" {
    			t := dat.(*TT) 
    			fmt.Println( t.aa, t.bb, t.cc )
    		}
    	}	
    
    B: 値を取出す
    	t3 := &TT{aa: "test", bb: 11, cc: 1234}
    	tt(t3)
    	
    	func tt(t interface{}){
    		c := reflect.ValueOf(t).Elem()
    		v := reflect.TypeOf(t).Elem()
    		
    		for i := 0 ; i < v.NumField(); i++ {
    			k := fmt.Sprint(v.Field(i).Name)
    			t := fmt.Sprint(c.FieldByName(k) )
    			fmt.Println( k, t )
    		}
    	}
    
  11. コンポジション (承継)
  12. type T2 struct{
    	Name string
    	TT
    }	
    	
    type TT struct{
    	Key string
    	Val int
    }	
    
    func(t *TT)Get(key string) int{ }
    func(t *TT)Set(key string,val int) error{ }
    
  13. 関数を変数に代入
  14. func tt() {
    	t1 := func(x, y float64) float64 {
    		return math.Sqrt(x*x + y*y)
    	}
    
    	fmt.Println(t1(3, 4))
    }
    
    // 関数のポインター
    var ff func( string ) error 
    
    if flag { 
    	ff = t1
    } else {
    	ff = t2
    }
    
    ff("aa")
    
    func t1(a string) error{ }
    func t2(a string) error{ }	
    
  15. 引数に関数を取る
  16. tt("test", t1)
    
    func tt( arg string, t2 func(string) error) { t2(arg) }
    func t1(a string) error{ }	
    
  17. Interface example
  18. type T interface {
    	get()  int
    	set(v int)
    }
    
    type T2 interface {
    	get2()  int
    }
    
    type t struct { v int }
    func (p *t) get() int { return p.v}
    func (p *t) set(v int) { p.v = v }
    
    type tt struct { 
    	t	// composition(inheritance)
    	val int
    }
    
    func (p *tt) get2() int {
    	p.val ++
    	return p.val
    }
    
    // composition(inheritance)
    func gett(a *tt){
    	x1 := a.get()
    	x2 := a.get2()
    	fmt.Println("gett:", x1, x2)
    }
    
    // tt has T interface
    func getT(b T){
    	x1 := b.get()
    	x2 := b.(T2).get2()
    	fmt.Println("getT:", x1, x2)
    }
    
    // tt has T2 interface
    func getT2(b T2){
    	x1 := b.(T).get()
    	x2 := b.get2()
    	fmt.Println("getT2:", x1, x2)
    }
    
    func main(){
    	t2 := &tt{} // new(tt)
    	t2.set(123)
    	
    	gett(t2)
    	getT(t2)
    	getT2(t2)
    }	
    
  19. type example
  20. // ----- interface -----
    type Any interface{}
    type T interface {
    	get() Any
    }
    
    type Value struct {
    	v Any
    }
    func (t *Value) get() Any {
    	return t.v
    }
    
    // ----- function -----
    type Sfunc func( string ) bool
    
    func testF1(arg string,ff Sfunc) bool{
    	return ff(arg)
    }
    
    func testF2() Sfunc{
    	return IsString
    }
    
    func IsString(s string) bool {
    	if tt := reflect.TypeOf(s).Name(); tt != "string" {
    		return false
    	}
    	return true
    }
    
    ret := testF1("aaa",IsString)
    
    ff := testF2()
    ret2 := ff("aa")
    

to IndexPage

First Release:2016-07-21