All uses of ellipsis - go

I am learning Go and it seems the ellipsis ... has at least 3 uses:
// #1: Array declarations
a := [...]int{1, 2, 3}
// #2: Variadic parameters
b := func (ints ...int) []int { return ints }(1, 2, 3)
// #3: Slice spread
c := append([]int{}, []int{1, 2, 3}...)
Does the ellipsis have other uses than the above 3?

As noted in the comments, these are all 3 use cases in the language, although the go tool uses ... as a path wildcard.

Related

My Go recursive function not working as expected due to slices

I have written a function and I can't seem to find where the bug is:
The function change works like this:
An input of 15 (target value) with possible values of [1, 5, 10, 25, 100] should return [5, 10]. That's because to reach a target value of 15, the least amount of numbers to make up that target number is to have a 10 and 5
I use a caching mechanism, as it is a recursive function and remembers the values that have already been calculated.
func Change(coins []int, target int, resultsCache map[int][]int) ([]int, error) {
if val, ok := resultsCache[target]; ok {
return val, nil
}
if target == 0 {
return make([]int, 0), nil
}
if target < 0 {
return nil, errors.New("Target can't be less than zero")
}
var leastNumOfCoinChangeCombinations []int
for _, coin := range coins {
remainder := target - coin
remainderCombination, _ := Change(coins, remainder, resultsCache)
if remainderCombination != nil {
combination := append(remainderCombination, coin)
if leastNumOfCoinChangeCombinations == nil || len(combination) < len(leastNumOfCoinChangeCombinations) {
leastNumOfCoinChangeCombinations = combination
}
}
}
if leastNumOfCoinChangeCombinations == nil {
return nil, errors.New("Can't find changes from coin combinations")
}
sort.Ints(leastNumOfCoinChangeCombinations)
resultsCache[target] = leastNumOfCoinChangeCombinations
return leastNumOfCoinChangeCombinations, nil
}
The cache however have some abnormal behaviour, for example if I want to use the value of 12 in the cache later, instead of getting [2,5,5], I get [1 2 5] instead. Not sure where I went wrong. (but initially it was calculated and stored correctly, not sure how it got changed).
Here is a playground I used for troubleshooting:
https://play.golang.org/p/Rt8Sh_Ul-ge
You are encountering a fairly common, but sometimes difficult to spot, issue caused by the way slices work. Before reading further it's probably worth scanning the blog post Go Slices: usage and internals. The issue stems from the way append can reuse the slices underlying array as per this quote from the spec:
If the capacity of s is not large enough to fit the additional values, append allocates a new, sufficiently large underlying array that fits both the existing slice elements and the additional values. Otherwise, append re-uses the underlying array.
The below code provides a simple demonstration of what is occurring:
package main
import (
"fmt"
"sort"
)
func main() {
x := []int{2, 3}
x2 := append(x, 4)
x3 := append(x2, 1)
fmt.Println("x2 before sort", x2)
sort.Ints(x3)
fmt.Println("x2 after sort", x2)
fmt.Println("x3", x3)
fmt.Println("x2 cap", cap(x2))
}
The results are (playground):
x2 before sort [2 3 4]
x2 after sort [1 2 3]
x3 [1 2 3 4]
x2 cap 4
The result is probably not what you expected - why did x2 change when we sorted x3? The reason this happens is that the backing array for x2 has a capacity of 4 (length is 3) and when we append 1 the new slice x3 uses the same backing array (capacity 4, length 4). This only becomes an issue when we make a change to the portion of the backing array used by x2 and this happens when we call sort on x3.
So in your code you are adding a slice to the map but it's backing array is then being altered after that instance of Change returns (the append/sort ends up happening pretty much as in the example above).
There are a few ways you can fix this; removing the sort will do the trick but is probably not what you want. A better alternative is to take a copy of the slice; you can do this by replacing combination := append(remainderCombination, coin) with:
combination := make([]int, len(remainderCombination)+1)
copy(combination , remainderCombination)
combination[len(remainderCombination)] = coin
or the simpler (but perhaps not as easy to grasp - playground):
combination := append([]int{coin}, remainderCombination...)

golang combination generation made an error

I'm dealing with a programming problem
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n.
and with input n = 5, k = 4, the output should be [[1,2,3,4],[1,2,3,5],[1,2,4,5],[1,3,4,5],[2,3,4,5]], the following is my golang solution
func combine(n int, k int) [][]int {
result := [][]int{}
comb := []int{}
subcom(0, k, n, &comb, &result)
return result
}
func subcom(s, k, n int, comb *[]int, result *[][]int) {
if k > 0 {
for i := s + 1; i <= n-k+1; i++ {
c := append(*comb, i)
subcom(i, k-1, n, &c, result)
}
} else {
*result = append(*result, *comb)
}
}
I think my solution is right, but it return [[1 2 3 5] [1 2 3 5] [1 2 4 5] [1 3 4 5] [2 3 4 5]].
After debugging, I found [1 2 3 4] was added to the result slice at the beginning, but later changed to [1 2 3 5], resulting in the repetition of two [1 2 3 5]s. But I can't figure out what's wrong here.
This is a common mistake when using append.
When your code runs c:=append(*comb,i), it tries to first use the allocated memory in the underlying array to add a new item and only create a new slice when it failed to do so. This is what changes the [1 2 3 4] to [1 2 3 5] - because they share the same underlying memory.
To fix this, copy when you want to append into result:
now := make([]int,len(*comb))
copy(now,*comb)
*result = append(*result,now)
Or use a shortcut of copying:
*result = append(*result, append([]int{},*comb...))
Update:
To understand what I mean by underlying memory, one should understandd the internal model of Go's slice.
In Go, a slice has a data structure called SliceHeader which is accessible through reflect package and is what being referred to when you use unsafe.Sizeof and taking address.
The SliceHeader taking cares of three elements: Len,Cap and a Ptr. The fisrt two is trivail: they are what len() and cap() is for. The last one is a uintptr that points to the memory of the data the slice is containing.
When you shallow-copy a slice, a new SliceHeader is created but with the same content, including Ptr. So the underlying memory is not copied, but shared.

Please explain if golang types pass by value

I'm trying to make a very simple program that modifies arrays, but ran across some interesting behavior if I converted them to types. https://play.golang.org/p/KC7mqmHuLw It appears that if I have an array go passes by reference, but if I have a type then go passes by value. Is this correct?
I have two variables b and c, both are arrays of 3 integers, but c is of type cT, in every other respect they should be identical. I can assign values as b[0]=-1 and c[0]=-1, but if I pass those arrays as parameters to a function they act very differently.
The output of the program is:
before b: [1 2 3]
before c: [1 2 3]
*after b: [-1 2 0]
*after c: [-1 2 3]
*what? c: [-1 2 0]
My initial assumption is that the lines "after b" and "after c" should have been the same. Am I doing something incorrectly or am I correct about types passing to functions by value (ie. creating copy of the variable before passing to the function)?
package main
import "fmt"
type cT [3]int
func main() {
b := []int{1, 2, 3}
c := cT{1, 2, 3}
fmt.Println("before b:", b)
fmt.Println("before c:", c)
b[0] = -1
c[0] = -1
mangleB(b) // ignore return value
mangleC(c) // ignore return value
fmt.Println("*after b:", b)
fmt.Println("*after c:", c)
c = mangleC(c)
fmt.Println("*what? c:", c)
}
func mangleB(row []int) []int {
row[2] = 0
return row
}
func mangleC(row cT) cT{
row[2] = 0
return row
}
The Go Programming Language Specification
Array types
An array is a numbered sequence of elements of a single type, called
the element type.
Slice types
A slice is a descriptor for a contiguous segment of an underlying
array and provides access to a numbered sequence of elements from that
array.
Calls
In a function call, the function value and arguments are evaluated in
the usual order. After they are evaluated, the parameters of the call
are passed by value to the function and the called function begins
execution. The return parameters of the function are passed by value
back to the calling function when the function returns.
type cT [3]int
b := []int{1, 2, 3}
c := cT{1, 2, 3}
I have two variables, b and c, both are arrays of 3 integers
No, you don't!
b is a slice of int with length (len(b)) 3 and capacity (cap(b)) 3, c is an array of (len(c)) 3 int.
In Go, all parameters are passed by value. b is passed as a slice descriptor, c is passed as an array. A slice descriptor is a struct with a slice length and capacity, and a pointer to the underlying array.
See comments:
func main() {
b := []int{1, 2, 3} // slice
c := cT{1, 2, 3} // array
fmt.Println("before b:", b)
fmt.Println("before c:", c)
b[0] = -1
c[0] = -1
// passing in a slice which you can think of as ref to array
// pass by value, and it is copy of ref to array
mangleB(b) // ignore return value
// passing in copy of array (pass by value)
// yes full shallow copy of array
mangleC(c) // ignore return value
// if you ignore return modifications are lost
fmt.Println("*after b:", b)
fmt.Println("*after c:", c)
// return value is modified array
c = mangleC(c)
// c now copy of array from line 24
fmt.Println("*what? c:", c)
}
when I'm calling slice a ref I'm simplifying details here https://blog.golang.org/go-slices-usage-and-internals
https://play.golang.org/p/OAaCMhc-Ug

Multiply 2 or more Arrays in Golang

maybe it's not just a Go-Problem but i have this problem:
I want to multiply two (or more) arrays, so for example:
a := [3]int{2, 3, 5}
b := [2]bool{true, false}
// desired output of "c" =>
// [[2 true] [2 false] [3 true] [3 false] [5 true] [5 false]]
I already found this library here: https://godoc.org/github.com/gonum/matrix/mat64 but i'm not seeing how to use something else than float64
The fallback-solution would be to use multiple for-range-loops but it'd be amazing if there is a "smoother" way to do this
Short answer: go is not intended for this kind of problem. What you want is an equivalent of the zip function, which is present natively in some languages (e.g. Haskell, Python, ...)
However, in Golang you'll have one big problem: you can't have dynamic types. That is: an array can contain only one type (int OR bool), not several. The workaround is to make an array of interface, but that means you'd have to make ugly type assertions to get the proper type back.
Also, you do have a general way to do that, but the type you'll get at the end will be [][]interface{} and no way of knowing what's inside.
For your example: here is the simplest way to do what you want (not general):
func main() {
a := [3]int{2, 3, 5}
b := [2]bool{true, false}
var c [6][2]interface{}
i := 0
for _, val1 := range a {
for _, val2 := range b {
c[i] = [2]interface{}{val1, val2}
i += 1
}
}
var a1 int = c[0][0].(int)
var b1 bool = c[0][1].(bool)
fmt.Printf("c[0] is %v, a1 is %d and b1 is %v\n", c[0], a1, b1)
fmt.Println(c)
}
As you can see, that's ugly and useless in practice (and very error-prone)
So, if you want to make this kind of transformations, you should use another language, Go was not (and won't) designed for this type of purposes.
This isn't a matrix multiplication, as pointed out above. The two for loops work if there are only two things, but if there are multiple ones it can clearly get tedious.
The way I would do it is to think of a multidimensional array. The total "number" of elements is the product of the sizes, and then use a function like SubFor https://godoc.org/github.com/btracey/meshgrid#SubFor
dims := []int{3,2}
sz := 1
for _,v := range dims {
sz *= v
}
sub := make([]int, len(dims))
for i := 0: i < sz; i++{
meshgrid.SubFor(sub, i, dims)
fmt.Println(a[sub[0]], b[sub[1]])
}
There are some things with types to figure out (appending to a slice, etc.), but that should give you the general gist.

Create array of array literal in Golang

How do I create an array of int arrays in Golang using slice literals?
I've tried
test := [][]int{[1,2,3],[1,2,3]}
and
type Test struct {
foo [][]int
}
bar := Test{foo: [[1,2,3], [1,2,3]]}
You almost have the right thing however your syntax for the inner arrays is slightly off, needing curly braces like; test := [][]int{[]int{1,2,3},[]int{1,2,3}} or a slightly more concise version; test := [][]int{{1,2,3},{1,2,3}}
The expression is called a 'composite literal' and you can read more about them here; https://golang.org/ref/spec#Composite_literals
But as a basic rule of thumb, if you have nested structures, you have to use the syntax recursively. It's very verbose.
In some other langauges (Perl, Python, JavaScript), [1,2,3] might be an array literal, but in Go, composite literals use braces, and here, you have to specify the type of the outer slice:
package main
import "fmt"
type T struct{ foo [][]int }
func main() {
a := [][]int{{1, 2, 3}, {4, 5, 6}}
b := T{foo: [][]int{{1, 2, 3}, {4, 5, 6}}}
fmt.Println(a, b)
}
You can run or play with that on the Playground.
The Go compiler is just tricky enough to figure out that the elements of an [][]int are []int without you saying so on each element. You do have to write out the outer type's name, though.
Just replace the square brackets with curly braces. In Go, array literals are identified with curly braces.
test := [][]int{{1,2,3},{1,2,3}}
A slice literal is written as []type{<value 1>, <value 2>, ... }. A slice of ints would be []int{1,2,3} and a slice of int slices would be [][]int{[]int{1,2,3},[]int{4,5,6}}.
groups := [][]int{[]int{1,2,3},[]int{4,5,6}}
for _, group := range groups {
sum := 0
for _, num := range group {
sum += num
}
fmt.Printf("The array %+v has a sum of %d\n", sub, sum)
}

Resources