4
3

More than 5 years have passed since last update.

MakeSlice と CanAddr

Posted at

つまったこと

ORMとかで引数にmapやsliceのポインタをinterface{}で受け付ける関数(Findなど)がある
⬇みたいなイメージ

results := make([]Users, 0, 16)
repository.Find(condition, &results)

reflect.Typeを使って、型を変えればデータ取得処理を使い回せる仕組みを実装しようとおもったら
reflect.MakeSliceで作ったSliceはCanAddr()がfalseになってしまうので、Addr()がつかえない
(中でappendとかされっかんね

samplse

package main

import "fmt"
import "reflect"


type User struct{}

func main() {

    userType := reflect.TypeOf(User{})

    userSlice := reflect.MakeSlice(reflect.SliceOf(userType), 0, 16)

    fmt.Printf("%#v\n", userSlice.CanAddr())
    // Output: false

    // panic !  
    //fmt.Printf("%#v\n", userSlice.Addr())
}

対応

ポインタを別途つくってやればよかった
reflectで操作をしていると、まだこの辺が混乱する

sample

package main

import "fmt"
import "reflect"


type User struct{}

func main() {

    userType := reflect.TypeOf(User{})

    userSlice := reflect.MakeSlice(reflect.SliceOf(userType), 0, 16)

    userSlicePointer := reflect.New(userSlice.Type())

    userSlicePointer.Elem().Set(userSlice)

    fmt.Printf("%#v\n", userSlicePointer.Interface())
    // Output: &[]main.User{}
}

チラ裏

reflectを多用すると、なぜか後ろめたい
眠いときは寝た方が良い

あえて…
_人人人人人_
> 寝るっ!! <
 ̄^Y^Y^Y^Y^ ̄

4
3
0

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
4
3