開発メモ

Dropbox API使うときに必要だったGo言語のinterface変数をより具体的な型の変数として扱う手段

February 24, 2019

型アサーション = interface変数をより具体的な型の変数として扱う手段

  • Go言語でinterface型の変数をダウンキャスト的に扱いたい場合は型アサーションが適用可能
 1type Hoge interface {
 2  fuga() string
 3}
 4
 5type Foo struct { }
 6func (f *Foo) fuga() string { return "fuga" }
 7func (f *Foo) piyo() string { return "piyo" }
 8
 9func main() {
10  h := Hoge(new(Foo))
11  fmt.Println(h.fuga())
12
13  original, ok := h.(*Foo)
14  if ok {
15    fmt.Println(original.piyo())
16  }
17}

Dropbox APIで型アサーションが必要になったポイント

 1type ListFolderResult struct {
 2	// Entries : The files and (direct) subfolders in the folder.
 3	Entries []IsMetadata `json:"entries"`
 4	// Cursor : Pass the cursor into `listFolderContinue` to see what's changed
 5	// in the folder since your previous query.
 6	Cursor string `json:"cursor"`
 7	// HasMore : If true, then there are more entries available. Pass the cursor
 8	// to `listFolderContinue` to retrieve the rest.
 9	HasMore bool `json:"has_more"`
10}
  • IsMetadataの実体がフォルダ(FolderMetadata)だったりファイル(FileMeatadata)だったりする
    • IsMetadataのデータを操作する場合はダウンキャスト的に具体的な型(subtype)として変数を扱う必要あり
    • この際,Go言語では上記型アサーションを使う
  • 以下,Dropboxで特定フォルダ配下にあるファイル名のみを列挙する処理の例
 1func main() {
 2	// initial setting
 3	token, path := <your-token>, <your-path>
 4	config := dropbox.Config{
 5		Token: dropboxToken,
 6	}
 7	dbx := files.New(config)
 8
 9  // get info under the 'path' folder
10	arg := files.NewListFolderArg(path)
11	resp, err := dbx.ListFolder(arg)
12	if err != nil {
13		return -1
14	}
15
16  // for each result
17	for _, e := range resp.Entries {
18    // type cast to check e is file or not
19		o, ok := e.(*files.FileMetadata)
20		if ok {
21      // if file, print the name of file
22			fmt.Println(o.Name)
23		}
24	}
25
26	return l 
27}

Tagged: #Go