Code duplication in Go switches

Just starting to write Go code, and I had an interesting problem.

Is there a way to easily iterate over elements in an array that is entered as an empty interface without duplicating code? Consider the following:

function(someArr interface{}){ switch someArr.(type){ case []int : arr := (someArr).([]int) for i := range (arr) { // CODE } case []string : arr := (someArr).([]string) for i := range (arr) { // CODE } } } 

In this example, the code in CODE is exactly the same. However, I cannot take this out of the switch, because a statement like arr will go beyond that. In the same way, I cannot define arr in front of the switch, because I do not know what type it will be. Perhaps this is simply not possible. Then what is the best idiom for this kind of thing when I, for example, parse JSON with an irregular scheme (some arrays ints, some arrays or strings)?

+4
source share
2 answers

You can use the reflect package to iterate over arbitrary fragments. But the implementation of special cases (for example, []int ) is clearly faster and often performed in addition to preventing reflection in ordinary cases.

 package main import "fmt" import "reflect" func foo(values interface{}) { rv := reflect.ValueOf(values) if rv.Kind() != reflect.Slice { return } n := rv.Len() for i := 0; i < n; i++ { value := rv.Index(i).Interface() fmt.Println(value) } } func main() { foo([]int{1, 3, 3, 7}) } 

Edit: I'm not sure why anyone voted for the question and my answer, but there are times when you need to deal with such code. Even the standard library contains a lot of things, see "fmt", "gob", "json", "xml" and "template", for example. The interrogator may face a similar problem.

+6
source

Your example is not an idiomatic Go code, although the idiomatic lexically also seems to violate the DRY principle.

The key to understanding is that “x” is a separate, differently typed variable in each case:

 function(someArr interface{}){ switch x := someArr.(type) { case []int: for i := range x { // CODE } case []string: for i := range x { // CODE } } } 
+6
source

Source: https://habr.com/ru/post/1498076/


All Articles