I am new to Go, and would like to copy an array (slice) into part of another. For example, I have a largeArray [1000]byte or something and a smallArray [10]byte and I want the first 10 bytes of largeArray to be equal to the contents of smallArray. I have tried:
largeArray[0:10] = smallArray[:]
But that doesn't seem to work. Is there a built-in memcpy-like function, or will I just have to write one myself?
Thanks!
Use the copy built-in function.
package main
func main() {
largeArray := make([]byte, 1000)
smallArray := make([]byte, 10)
copy(largeArray[0:10], smallArray[:])
}
Related
I am using the Go flatbuffers interface for the first time. I find the instructions sparse.
I would like to write a vector of uint64s into a table. Ideally, I would like to store numbers directly in a vector without knowing how many there are up front (I'm reading them from sql.Rows iterator). I see the generated code for the table has functions:
func DatasetGridAddDates(builder *flatbuffers.Builder, dates flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(dates), 0)
}
func DatasetGridStartDatesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
return builder.StartVector(8, numElems, 8)
}
Can I first write the vector using (??), then use DatasetGridAddDates to record the resulting vector in the containing "DatasetGrid" table?
(caveat: I have not heard of FlatBuffers prior to reading your question)
If you do know the length in advance, storing a vector is done as explained in the tutorial:
name := builder.CreateString("hello")
q55310927.DatasetGridStartDatesVector(builder, len(myDates))
for i := len(myDates) - 1; i >= 0; i-- {
builder.PrependUint64(myDates[i])
}
dates := builder.EndVector(len(myDates))
q55310927.DatasetGridStart(builder)
q55310927.DatasetGridAddName(builder, name)
q55310927.DatasetGridAddDates(builder, dates)
grid := q55310927.DatasetGridEnd(builder)
builder.Finish(grid)
Now what if you don’t have len(myDates)? On a toy example I get exactly the same output if I replace StartDatesVector(builder, len(myDates)) with StartDatesVector(builder, 0). Looking at the source code, it seems like the numElems may be necessary for alignment and for growing the buffer. I imagine alignment might be moot when you’re dealing with uint64, and growing seems to happen automatically on PrependUint64, too.
So, try doing it without numElems:
q55310927.DatasetGridStartDatesVector(builder, 0)
var n int
for rows.Next() { // use ORDER BY to make them go in reverse order
var date uint64
if err := rows.Scan(&date); err != nil {
// ...
}
builder.PrependUint64(date)
n++
}
dates := builder.EndVector(n)
and see if it works on your data.
For printing, justified and fixed length, seems like what everyone asks about and there are many examples that I have found, like...
package main
import "fmt"
func main() {
values := []string{"Mustang", "10", "car"}
for i := range(values) {
fmt.Printf("%10v...\n", values[i])
}
for i := range(values) {
fmt.Printf("|%-10v|\n", values[i])
}
}
Situation
But what if I need to WRITE to a file with fixed length bytes?
For example: what if I have requirement that states, write this line to a file that must be 32 bytes, left justified and padded to the right with 0's
Question
So, how do you accomplish this when writing to a file?
There are analogous functions to fmt.PrintXX() functions, ones that start with an F, take the form of fmt.FprintXX(). These variants write the result to an io.Writer which may be an os.File as well.
So if you have the fmt.Printf() statements which you want to direct to a file, just change them to call fmt.Fprintf() instead, passing the file as the first argument:
var f *os.File = ... // Initialize / open file
fmt.Fprintf(f, "%10v...\n", values[i])
If you look into the implementation of fmt.Printf():
func Printf(format string, a ...interface{}) (n int, err error) {
return Fprintf(os.Stdout, format, a...)
}
It does exactly this: it calls fmt.Fprintf(), passing os.Stdout as the output to write to.
For how to open a file, see How to read/write from/to file using Go?
See related question: Format a Go string without printing?
At the moment I have a go program that contains the following code.
package main
import "time"
import "minions/minion"
func main() {
// creating the slice
ms := make([]*minion.Minion, 2)
//populating the slice and make the elements start doing something
for i := range ms {
m := &ms[i]
*m = minion.NewMinion()
(*m).Start()
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for i := range ms {
m := &ms[i]
(*m).Stop()
}
}
Here NewMinion() is a constructor that returns a *minion.Minion
The code works perfectly, but having to write m := &ms[i] every time I use a for ... range loop seems to me like there should be a code writer friendlier way to tackle this problem.
Ideally I'd like something like the following to be possible (using the made up &range tag):
package main
import "time"
import "minions/minion"
func main() {
// creating the slice
ms := make([]*minion.Minion, 2)
//populating the slice and make the elements start doing something
for _, m := &range ms {
*m = minion.NewMinion()
(*m).Start()
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for _, m := &range ms {
(*m).Stop()
}
}
Unfortunately, this is not a language feature as of yet. Any considerations on what would be the nicest way remove the m := &ms[i] from the code? Or is there no way yet that takes less effort to write than this?
Your first example is a slice of pointers, you don't need to take the address of the pointers in the slice and then dereference the pointers each time. More idiomatic Go would look like (edited slightly to run in the playground without the "minion" package):
http://play.golang.org/p/88WsCVonaL
// creating the slice
ms := make([]*Minion, 2)
//populating the slice and make the elements start doing something
for i := range ms {
ms[i] = NewMinion(i)
ms[i].Start()
// (or equivalently)
// m := MewMinion(i)
// m.Start()
// ms[i] = m
}
// wait while the minions do all the work
time.Sleep(time.Millisecond * 500)
// make the elements of the slice stop with what they were doing
for _, m := range ms {
m.Stop()
}
This is all wrong.
There is absolutely no need to take the address of a pointer in your code. ms is a slice of pointers and you constructor returns a pointer so just assign i directly:
for i := range ms {
ms[i] = minion.NewMinion()
ms[i].Start()
}
Dead simple.
This question already has answers here:
Copying all elements of a map into another
(4 answers)
Closed 4 months ago.
Is there a built in function in go for making copies of arbitrary maps?
I would be able to write one by hand but I found out earlier I was looking a similar question when I wanted to make a deep comparison of maps and there seemed to be a function already built in for that! So similarly, maybe I was wondering if there was an built in or some library or package for making deep copies of maps in golang. I am sure I am not the first person to want to make copies of maps in go.
By copy I mean you can create two different variables that reference a different map in memory even though they are the same content wise.
For a more general answer, you can encode your map and decode it in a new variable with encoding/gob.
The advantages of this way is that it'll even work on more complex data structure, like a slice of struct containing a slice of maps.
package main
import (
"bytes"
"encoding/gob"
"fmt"
"log"
)
func main() {
ori := map[string]int{
"key": 3,
"clef": 5,
}
var mod bytes.Buffer
enc := gob.NewEncoder(&mod)
dec := gob.NewDecoder(&mod)
fmt.Println("ori:", ori) // key:3 clef:5
err := enc.Encode(ori)
if err != nil {
log.Fatal("encode error:", err)
}
var cpy map[string]int
err = dec.Decode(&cpy)
if err != nil {
log.Fatal("decode error:", err)
}
fmt.Println("cpy:", cpy) // key:3 clef:5
cpy["key"] = 2
fmt.Println("cpy:", cpy) // key:2 clef:5
fmt.Println("ori:", ori) // key:3 clef:5
}
If you want to know more about gobs, there is a go blog post about it.
No, there is no built-in one-liner for map deep copy.
However, there is an iterative solution as well as a generic package for deep copy.
Copying a map is a few, trivial lines of code. Just write the code and enjoy letting go of the idea that every simple piece of code has to be in a library!
original := map[string]int{
"Hello": 4,
"World": 123,
}
copy := map[string]int{}
for k, v := range original {
copy[k] = v
}
This question already has answers here:
Generic variadic argument in Go?
(3 answers)
Closed 8 months ago.
Let's say I want to make the equivalent of the JavaScript Array.splice function in Go, for Slices. I have the following code:
func splice(slice []int, index, amount int, elements ...int) []int {
newslice := make([]int, 0)
for i := 0; i < index; i++ {
newslice = append(newslice, slice[i])
}
for i := index + amount; i < len(slice); i++ {
newslice = append(newslice, slice[i])
}
for _, el := range elements {
newslice = append(newslice, el)
}
return newslice
}
This example will work, but only for arguments of type int. I want to make it generic, and I know that I should give the variadic argument elements the type interface{}, but how do I create a new slice with the type of that interface from inside the function?
In other words, how can I specify the type of the slice dynamically depending on the type of the arguments in the first line of the function, where newslice is created?
Using reflection
If you really want to do generic stuff, reflection is the ultimate answer.
See the MakeSlice documentation
in the reflection package for details on your problem.
You just need to retrieve the type of the incoming slice (using TypeOf(...))
and applying MakeSlice correctly.
Example of using reflection to create a slice:
y := []int{1,2,3}
t := reflect.TypeOf(y)
slice := reflect.MakeSlice(t, 0, 10)
slice = reflect.Append(slice, reflect.ValueOf(2))
fmt.Println(slice.Interface())
Run it here.
Using []interface{}
Another way to work with, is []interface{}, which can store any value
but may lead to runtime panics as you omit compiler type checking completely
(this is a bad thing).
Here is an example for using []interface{}
as storage for arbitrary values. With this you don't need to know the type in
your splice implementation, you just splice and use []interface{} for new slices.
This method has the drawback, that you can't convert some slice to []interface{} easily. You have to copy it manually, as described in posts before.
Conclusion
Regardless of which version you use, you will never get back type safety without
knowing the type and converting it back manually. There's no such thing in Go
which will do that for you. That means, that you'll have something like this
in your code to regain type safety:
x := []int{1,2,3,4}
y := splice(x, ...)
yn := []int(y)
Instead of emulating JavaScript in Go (why ???) I would like to suggest to compose simmilar required operations from the building blocks of SliceTricks.
They are:
Completely type agnostic (think "generics" for free).
Quite probably pretty faster compared to packing/unpacking whatsoever in/from a []interface{}.