LoginSignup
8
3

More than 3 years have passed since last update.

goで楽して実装したいので、チート集っぽいマルチ型変換を作って、オープンソースで公開したよ

Last updated at Posted at 2019-12-05

まとめると

  • goで型やデータ変換に関して、実装したり探したりするのは簡単だけど面倒
  • 変換するライブラリを作成
  • オープンソースで公開した。簡単な実装なのでサンプルコード集としても使える。
  • もちろん対応してない変換も多々ある。(今後も増やしていく)

概要

goではたまに別の型へ変数を入れたり、interface{}という何でも入れられる変数を経由して受け渡したりして、そのたびに(簡単だけど)変換処理をする必要がある。

一回一回実装しても良いけど手が疲れて来るので、とりあえず、どんな型で受け取るかは知らんが、ほしい型の変数に変換できるお手軽な(こったやつではない)ものが欲しいなぁと思って、作ってみた。

ToString(v interface{}) みたいな雰囲気で、何も考えずにぶっこむ形を意識。

できあがった形

    v := 2
    s := typeconv.ToString(v).A
    fmt.Println(s)

出力結果はもちろん2。
「.A」は「Q&AのA」。
わざわざAってついている理由は、「.IsNil」とか「.NoStruct」とか「.Error」とか他の情報がくっついてきたりする。変換によって何がくっついてくるのかは違う。
今後も必要な情報があれば拡張できる。

戻り値を複数にしなかったのは、

fmt.Println(typeconv.ToInt("100").A)

こんな感じで書けるようにしたかったから。
目的は「楽に実装できる」
ただ、エラーを踏み潰す場合もあるので、エラーが出そうな変換は

    s := typeconv.ToInt("www")
    if s.Error != nil {
        何か処理
    }
    fmt.Println(s.A)

nilの場合はデフォルト値が使われる
デフォルト値も変更できる

fmt.Println(typeconv.ToString(nil, "にる").A)

ソース見るとデフォルト値を複数渡せそうだが、1個目しか使わない。省略するか、1個書くかのどちらか。

個別にデフォルト値を設定するのも面倒になってきた人は、こんな感じで書けるようにもした。

typeconv.DefaultString = ""
typeconv.DefaultInt = -1

導入

go get -u github.com/daikuro/GoTypeConvert

基本(intからstringへ)

import (
  typeconv "github.com/daikuro/GoTypeConvert"
)

func main() {
    v := 2
    s := typeconv.ToString(v).A
    fmt.Println(s)
}

出力結果
2

使い方:stringからint

import (
  typeconv "github.com/daikuro/GoTypeConvert"
)

func main() {
    var v interface{}
    v = "2"
    s := typeconv.ToInt(v).A
    fmt.Println(s)
}

結果
2

サンプル:stringからbool

    fmt.Println(ToBool("true").A)
    // Output:
    // true

サンプル: structからmap[string]

type User struct { 
  Name string 
}

user := &User{
  Name: "TestName",
}

a := ToMap(user).A
fmt.Println(a)

出力結果
map[Name:TestName]

サンプル: mapからstruct

    type User struct {
        Name  string
        Items []string
    }
    o := &User{}
    MapToInterface(o, map[string]interface{}{
        "Name":  "testUser",
        "Items": []string{"A", "B"},
    })
    fmt.Println(o.Name)
    fmt.Println(o.Items)
    // Output:
    // testUser
    // [A B]

使い方: map[string]interface{[]interface}からstruct

    type User struct {
        Name  string
        Items []string
    }
    o := &User{}
    MapToInterface(o, map[string]interface{}{
        "Name":  "testUser",
        "Items": []interface{}{"A", "B"},
    })
    fmt.Println(o.Name)
    fmt.Println(o.Items)
    // Output:
    // testUser
    // [A B]

使い方: map[string]interface{[]interface {string, string, int}}からstruct

ここは趣味の世界

    type User struct {
        Name  string
        Items []string
    }
    o := &User{}
    MapToInterface(o, map[string]interface{}{
        "Name":  "testUser",
        "Items": []interface{}{"A", "B", 1},
    })
    fmt.Println(o.Name)
    fmt.Println(o.Items)
    // Output:
    // testUser
    // [A B 1]

使い方:文字列からio.Reader

    r := ToIoReader("value").A

使い方:base64から[]byteからstring

    fmt.Println(ToString(Base64To("dmFsdWU=").A).A)
    // Output:
    // value

Base64Toに関してはString()メソッドも用意

    fmt.Println(Base64To("dmFsdWU=").String())
    // Output:
    // value

他の使い方

テストコードを見てね!
読みやすいテストコードを意識した。

GitHub

今後

面倒な変換はどんどん増やしたい。(サンプルコード集として)

8
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
3