Is byte slice in Golang a 2d data structure - go

I got this code off some blog, I want to know why the reassignment of a particular index in the slice b is denoted using a 2d indexing, example
b[0][0] = byte('*')
Isn't it supposed to be
b[0]=byte('*')
package main
import (
"bytes"
"fmt"
)
func splitDemo() {
fmt.Println("Split demo")
a := []byte("a,b,c")
b := bytes.Split(a, []byte(","))
b[0][0] = byte('*')
fmt.Printf("%q",b)
fmt.Printf("%q",a)
}
func main() {
splitDemo()
}

bytes.Split returns a [][]byte. That's a slice of []byte.

Related

Golang reflection slice shows up as struct

package main
import (
"fmt"
"encoding/json"
"reflect"
)
func someFunc( data interface{}, out interface{} ) {
v := reflect.ValueOf(out).Elem();
fmt.Printf("Incoming type: %s\n",reflect.ValueOf(v).Kind())
v.SetCap(reflect.ValueOf(data).Len())
}
func main() {
expected := []int{1,2,3}
jsonRaw, _ := json.Marshal(expected)
var tmpData interface{}
json.Unmarshal(jsonRaw, &tmpData)
fmt.Printf("%s\n",string(jsonRaw))
fmt.Printf("%#v\n",tmpData)
result := []int{}
var tmp interface{}
tmp = result
fmt.Printf("Outcoming type: %s\n",reflect.TypeOf(&tmp))
someFunc(tmpData,&tmp)
}
I would like to operate on v parameter inside someFunc as if it were
a slice, i.e. "Incoming type"-debug message should output slice.
However, it outputs struct, as is shown here.
The ultimate goal is that I use reflection to analyze the data-parameter's contents and recover everything into out, but for now I would like to
know how to make sure the correct type of v is detected,
so that I can use it as a slice.
EDIT: It appears to be impossible (as of 2013 at least): https://groups.google.com/forum/#!topic/golang-nuts/bldM9tIL-JM
to set the size of a slice for stuff discovered at runtime.
One of the authors says something to the effect that "you have to be able
to sort the elements, i.e. implement Less()" for the values...
EDIT: In any case, I did try to use MakeSlice in this Playgound link,
and it says reflect.MakeSlice of non-slice type
EDIT: I apologize and thank you all for your comments.
What I ended up doing is the following (after an illuminating read of the source code of MakeSlice):
package main
import (
"fmt"
"encoding/json"
"reflect"
)
func someFunc( data interface{}, out interface{} ) {
v := reflect.ValueOf(out).Elem();
fmt.Printf("Incoming type: %s\n",v.Kind())
//v.SetCap(reflect.ValueOf(data).Len()) <-- doesn't work
n := reflect.ValueOf(data).Len()
s := reflect.MakeSlice(reflect.TypeOf(data),n,n)
fmt.Printf("Len= %d\n",s.Len())
}
func main() {
expected := []int{1,2,3}
jsonRaw, _ := json.Marshal(expected)
var tmpData interface{}
json.Unmarshal(jsonRaw, &tmpData)
fmt.Printf("%s\n",string(jsonRaw))
fmt.Printf("%#v\n",tmpData)
result := []int{}
someFunc(tmpData,&result)
}
What I ended up doing is the following (after an illuminating read of the source code of MakeSlice):
package main
import (
"fmt"
"encoding/json"
"reflect"
)
func someFunc( data interface{}, out interface{} ) {
v := reflect.ValueOf(out).Elem();
fmt.Printf("Incoming type: %s\n",v.Kind())
//v.SetCap(reflect.ValueOf(data).Len()) <-- doesn't work
n := reflect.ValueOf(data).Len()
s := reflect.MakeSlice(reflect.TypeOf(data),n,n)
fmt.Printf("Len= %d\n",s.Len())
}
func main() {
expected := []int{1,2,3}
jsonRaw, _ := json.Marshal(expected)
var tmpData interface{}
json.Unmarshal(jsonRaw, &tmpData)
fmt.Printf("%s\n",string(jsonRaw))
fmt.Printf("%#v\n",tmpData)
result := []int{}
someFunc(tmpData,&result)
}
It appears that there are convenience functions such as SliceOf, too.
the bottomline is that the first argument of MakeSlice is not the type
of the arguments that the slice holds, but the slice-type, e.g. []int rather than int.

How can I parse []int JSON data in Go?

I try parse JSON data include integer array. But, I can't get integer array.
package main
import (
"encoding/json"
"fmt"
)
type Anything struct {
A []int `json:"a"`
}
func main() {
s := "{a:[1,2,3]}"
var a Anything
json.Unmarshal([]byte(s), &a)
fmt.Println(a.A)
}
I got empty array.
[]
How can I get [1, 2, 3]?
{a:[1,2,3]} is not valid JSON. Object keys must be double-quoted. Changing it like this works as expected:
s := "{\"a\":[1,2,3]}"
https://play.golang.org/p/qExZAeiRJy
You have an invalid JSON. You should replace it, for example like this: s := [{"a":[1,2,3]}] or maybe like this s := "[{\"a\":[1,2,3]}]".
You can edit your code to something like this:
package main
import (
"encoding/json"
"fmt"
)
type Anything struct {
A []int `json:"a"`
}
func main() {
// note here: `[{"a":[1,2,3]}]`
// or: s := "[{\"a\":[1,2,3]}]"
s := `[{"a":[1,2,3]}]`
var a []Anything
json.Unmarshal([]byte(s), &a)
fmt.Println(a)
}
Output:
[{[1 2 3]}]
You can run it on https://play.golang.org/p/H4GupGFpfP

Can Go functions specify a particular array length?

Does Go allow functions to add array length constraints to the signature, or would length still require a runtime check?
For arrays it is more than possible, it is required. For slices it is impossible.
package main
import (
"fmt"
)
func main() {
d := [2]int{1, 2}
fmt.Println(sum(d))
}
func sum(data [2]int) int {
return data[0] + data[1]
}
https://play.golang.org/p/-VMxyDvwUt

Golang reflect, how to get map value type?

For a map m in golang, we can get simply the key type using t.Key().
But I wonder how to get the map value type?
When the map is empty, we can not even use v.MapIndex, any idea?
m := map[string]int{}
t := reflect.TypeOf(m)
v := reflect.ValueOf(m)
t.Key()
v.MapIndex()
Elem() of a map type will give you the element's type:
var m map[string]int
fmt.Println(reflect.TypeOf(m).Elem())
// output: int
Here an example to get the type of the map keys and map elements:
package main
import (
"fmt"
"reflect"
)
func main() {
fmt.Println("Hello, playground")
var m map[string]int
fmt.Println(reflect.TypeOf(m).Key())
fmt.Println(reflect.TypeOf(m).Elem())
}
Playground here
Doc is here https://golang.org/pkg/reflect/#Type

Get the length of a slice of unknown type

Let's say I have a function that returns an interface{}. But I know that item returns is a slice of some kind. How can I determine the length of that slice? Here's sample code of what I tried, but they all cause compilation error.
package main
import (
"log"
"reflect"
)
func SomeKindOfSlice() interface{} {
return []int64{0,1,2,3,4,5,6,7,8,9}
}
func main() {
slice := SomeKindOfSlice()
/*log.Println(reflect.TypeOf(slice).Len())
log.Println(reflect.TypeOf(slice).Type().Len())
log.Println(reflect.ValueOf(slice).Type().Len())
log.Println(reflect.ValueOf(slice).Elem().Type().Len())
*/
log.Println(reflect.ValueOf(slice).Elem().Type().Len())
}
I'd like to avoid the brute force way of specifically type asserting the slice variable just to find the length.
In your current attempt of the refect package usage you are querying for the Len of the Type. So this assumes you are dealing with an array not a slice. The difference being that a array is a fixed size slice, a slice has unbound length.
Check this code for demonstration
package main
import (
"log"
"reflect"
)
func SomeKindOfSlice() interface{} {
return []int64{0,1,2,3,4,5,6,7,8,9}
}
func SomeKindOfArray() interface{} {
return [10]int64{0,1,2,3,4,5,6,7,8,9}
}
func main() {
log.Println(reflect.ValueOf(SomeKindOfSlice()).Len())
log.Println(reflect.ValueOf(SomeKindOfArray()).Type().Len())
}

Resources