Interface Inside Struct

474 views
Skip to first unread message

Tomi Häsä

unread,
Mar 5, 2016, 2:29:50 PM3/5/16
to golang-nuts
Placing an interface inside a struct might not be the best option in every case, but I was wondering how do I create a factory function for such a struct? Below is my failed example.

If I remove the comments from the factory function, I get:

invalid type for composite literal: Counter


If I remove the Counter{} argument, I get:


too few values in struct initializer


If I put Counter as an argument, I get:


type Counter is not an expression


Code:


/**********************************************************************
 * Interface inside struct                                            *
 *********************************************************************/

package main
import "fmt"


type Counter interface {
    increase()
    decrease()
    nothing()   // testing
}


type Number struct {
    value  int
    co     Counter
}


// factory function
//func NewNumber( x int ) *Number {
//    return &Number{ x, Counter{} }
//}


func (nu Number) increase() {
    a := nu.value
    a++
    fmt.Printf( "My value: %d \n", a )

    nu.value = a
    fmt.Printf( "Increasing myself: %d \n", number.value )
    
    //nu.value = nu.value + 1
}


func (nu Number) decrease() {
    //a := nu.value
    //a--
    //nu.value = a

    nu.value--
}


func (nu Number) nothing() {
    nu.value = nu.value
}


var (

    number Number
)


func main() {

    number.value = 0
    fmt.Printf(  "Number in the beginning: %d \n", number.value )
    number.increase()
    fmt.Printf(  "Increased number:  %d \n", number.value )
    fmt.Println()
}

If I run this program I get:

Number in the beginning: 0 

My value: 1 

Increasing myself: 0 

Increased number:  0 



Justin Israel

unread,
Mar 5, 2016, 2:44:13 PM3/5/16
to Tomi Häsä, golang-nuts

To fix the error in your factory function, try replacing Counter{} with nil.
Counter is an interface and not a concrete type, so you cannot construct instances of an interface like that.

Although I am not clear why your Number struct implements your Counter interface, as well as wanting to store a Counter interface field. That aspect has no relation to your desire to have a factory function and have a Counter interface field on your struct.

Justin


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Nico

unread,
Mar 6, 2016, 2:17:41 AM3/6/16
to golan...@googlegroups.com
On 05/03/16 19:29, Tomi Häsä wrote:
> Placing an interface inside a struct might not be the best option in every case, but I was wondering how do I create a factory function for such a struct? Below is my failed example.

Just, use nil (see the updated code below).

---

I would also read this FAQ entry https://golang.org/doc/faq#methods_on_values_or_pointers .

---

https://play.golang.org/p/CId4GQWg6u

package main

import "fmt"

type Counter interface {
increase()
decrease()
nothing() // testing
}

type Number struct {
value int
co Counter
}

func NewNumber(value int) *Number {
return &Number{value, nil}
}

func (nu *Number) increase() {
a := nu.value
a++
fmt.Printf("My value: %d \n", a)

nu.value = a
fmt.Printf("Increasing myself: %d \n", number.value)

nu.value = nu.value + 1
}

func (nu *Number) decrease() {
nu.value--
}

func (nu *Number) nothing() {

Krzysztof Kowalczyk

unread,
Mar 6, 2016, 11:48:07 PM3/6/16
to golang-nuts
To reiterate what Justin said, embedding Counter inside Number does nothing in this particular example and probably isn't what you meant. 

Type (Number) conforms to interface (Counter) by implementing interface methods. What you probably meant is just this:
package main

import "fmt"

type Counter interface {
increase()
decrease()
nothing() // testing
}

type Number struct {
value int
}

func NewNumber(value int) *Number {
return &Number{value}
}

func (nu *Number) increase() {
a := nu.value
a++
fmt.Printf("My value: %d \n", a)

nu.value = a
fmt.Printf("Increasing myself: %d \n", number.value)

nu.value = nu.value + 1
}

func (nu *Number) decrease() {
nu.value--
}

func (nu *Number) nothing() {
nu.value = nu.value
}

var (
number Number
)

func main() {
number.value = 0
fmt.Printf("Number in the beginning: %d \n", number.value)
number.increase()
fmt.Printf("Increased number:  %d \n", number.value)
fmt.Println()
}


Reply all
Reply to author
Forward
0 new messages