- ... (three dots)
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
}
- interface
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)
}
- interface and three dots
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)
}
}
}
- 引数が interface
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)
}
- struct を interface で受取る
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 )
}
}
- コンポジション (承継)
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{ }
- 関数を変数に代入
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{ }
- 引数に関数を取る
tt("test", t1)
func tt( arg string, t2 func(string) error) { t2(arg) }
func t1(a string) error{ }
- Interface example
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)
}
- type example
// ----- 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")