Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

General slice type in golang?

Tags:

types

slice

go

I'm having some difficulties trying to extend slice types into a general type in Go. I have created a sample code to explain my problem. play ground version

package main

import "fmt"

type Sequencer interface {
    Mean() float64
}

type Sequence []int

func (s Sequence) Mean() float64 {
    sum := 0.0
    for _, el := range s {
        sum += float64(el)
    }
    return sum / float64(len(s))
}

func main() {
    a := []int{1, 2, 3, 4}
    b := Sequence(a)
    fmt.Println(b.Mean())
    fmt.Println(b[:2].Mean())
    c := Sequencer(b)
    fmt.Println(c.Mean())
    fmt.Println(c[:2].Mean())
}

Last line of the main() function returns an error saying that variables of type Sequencer cannot be sliced:

cannot slice c (type Sequencer)

Is there a way of defining a general type of slices (int, float64, string,...) without hiding the cool indexing capabilities of slices?

like image 299
prl900 Avatar asked Dec 20 '22 13:12

prl900


1 Answers

You have

type Sequencer interface {
    Mean() float64
}

c := Sequencer(b)

Therefore, the variable c contains a value of some type which satisfies the Sequencer interface; the type has a Mean method. That's all we can say, no more, no less. It does not imply that the variable c value can be sliced. Therefore, the slice expression c[:2] is invalid. For example, we could define a type Map which satisfies the Sequencer interface but cannot be sliced. If you want to slice c then assert that it is of a type that can be sliced, for example, c.(Sequence)[:2].

package main

import "fmt"

type Sequencer interface {
    Mean() float64
}

type Sequence []int

func (s Sequence) Mean() float64 {
    sum := 0.0
    for _, el := range s {
        sum += float64(el)
    }
    return sum / float64(len(s))

}

type Map map[string]float64

func (m Map) Mean() float64 {
    sum := 0.0
    for _, v := range m {
        sum += float64(v)
    }
    return sum / float64(len(m))

}

func main() {
    a := []int{1, 2, 3, 4}
    b := Sequence(a)
    fmt.Println(b.Mean())
    fmt.Println(b[:2].Mean())
    c := Sequencer(b)
    fmt.Println(c.Mean())
    fmt.Println(c.(Sequence)[:2].Mean())
    m := Map{"one": 3.14159, "two": 2.718}
    fmt.Println(m.Mean())
}

Output:

2.5
1.5
2.5
1.5
2.929795
like image 147
peterSO Avatar answered Jan 02 '23 04:01

peterSO