FAQ
Dear all,

I have a question about interfaces: A concrete type which implements an
interface can be used as a function argument, when the function expects the
interface type. Example: If I have the following code,

type Number interface {
Value() float64
}

type Rational struct {
Numerator, Denominator int
}

func ThisWorks(x Number) {
fmt.Println(x.Value())
}


then I can call ThisWorks(&Rational{1, 2}). In contrast, a function
returning the concrete type cannot be used in when a function returning the
interface type is expected: If I have

func GetRationalNumber() *Rational {
return &Rational{1, 2}
}

func ThisDoesNotWork(fn func() Number) {
x := fn()
fmt.Println(x.Value())
}


then I cannot use ThisDoesNotWork(GetRationalNumber). Code to play with is
here: http://play.golang.org/p/wpWAOaD4QT

My question: Why does this not work? Is this something which may be
changed in a future version of Go? Or is there a (technical or design)
reason why a function returning a concrete type cannot be used in place of
a function returning a compatible interface type?

Many thanks,
Jochen

PS.: I know that I could change GetRationalNumber to return type Number in
the above example. My question is not about how to fix my code, but about
why Go is the way it is in this regard.

--
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+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Search Discussions

  • Jasdel at Nov 8, 2015 at 7:05 pm
    This doesn't work because

         func() Number

    Is a different type than

         func() *Rational

    And go is unable to convert between the two automatically. The interface
    usage can only be applied on the parent type it self not nested types. This
    is also why []string cannot be set to a []interface{} type. Manual
    conversion is needed.

    I cannot speak as to why Go does this other than to guess out of keeping
    the interface rules simple.

    Cheers,
    jasdel
    On Sunday, November 8, 2015 at 10:25:46 AM UTC-8, Jochen Voss wrote:

    Dear all,

    I have a question about interfaces: A concrete type which implements an
    interface can be used as a function argument, when the function expects the
    interface type. Example: If I have the following code,

    type Number interface {
    Value() float64
    }

    type Rational struct {
    Numerator, Denominator int
    }

    func ThisWorks(x Number) {
    fmt.Println(x.Value())
    }


    then I can call ThisWorks(&Rational{1, 2}). In contrast, a function
    returning the concrete type cannot be used in when a function returning the
    interface type is expected: If I have

    func GetRationalNumber() *Rational {
    return &Rational{1, 2}
    }

    func ThisDoesNotWork(fn func() Number) {
    x := fn()
    fmt.Println(x.Value())
    }


    then I cannot use ThisDoesNotWork(GetRationalNumber). Code to play with
    is here: http://play.golang.org/p/wpWAOaD4QT

    My question: Why does this not work? Is this something which may be
    changed in a future version of Go? Or is there a (technical or design)
    reason why a function returning a concrete type cannot be used in place of
    a function returning a compatible interface type?

    Many thanks,
    Jochen

    PS.: I know that I could change GetRationalNumber to return type Number in
    the above example. My question is not about how to fix my code, but about
    why Go is the way it is in this regard.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Roberto Zanotto at Nov 8, 2015 at 7:11 pm
    I guess one reason is that when a function returns a concrete type and you
    want to assign it to an interface variable, the interface that wraps the
    concrete type must be created. So you must know at compile time if the
    function returns a concrete value or an interface, with a func variable the
    thing does not work.
    On Sunday, November 8, 2015 at 7:25:46 PM UTC+1, Jochen Voss wrote:

    Dear all,

    I have a question about interfaces: A concrete type which implements an
    interface can be used as a function argument, when the function expects the
    interface type. Example: If I have the following code,

    type Number interface {
    Value() float64
    }

    type Rational struct {
    Numerator, Denominator int
    }

    func ThisWorks(x Number) {
    fmt.Println(x.Value())
    }


    then I can call ThisWorks(&Rational{1, 2}). In contrast, a function
    returning the concrete type cannot be used in when a function returning the
    interface type is expected: If I have

    func GetRationalNumber() *Rational {
    return &Rational{1, 2}
    }

    func ThisDoesNotWork(fn func() Number) {
    x := fn()
    fmt.Println(x.Value())
    }


    then I cannot use ThisDoesNotWork(GetRationalNumber). Code to play with
    is here: http://play.golang.org/p/wpWAOaD4QT

    My question: Why does this not work? Is this something which may be
    changed in a future version of Go? Or is there a (technical or design)
    reason why a function returning a concrete type cannot be used in place of
    a function returning a compatible interface type?

    Many thanks,
    Jochen

    PS.: I know that I could change GetRationalNumber to return type Number in
    the above example. My question is not about how to fix my code, but about
    why Go is the way it is in this regard.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Ian Lance Taylor at Nov 8, 2015 at 7:24 pm

    On Sun, Nov 8, 2015 at 10:25 AM, Jochen Voss wrote:
    I have a question about interfaces: A concrete type which implements an
    interface can be used as a function argument, when the function expects the
    interface type. Example: If I have the following code,

    type Number interface {
    Value() float64
    }

    type Rational struct {
    Numerator, Denominator int
    }

    func ThisWorks(x Number) {
    fmt.Println(x.Value())
    }


    then I can call ThisWorks(&Rational{1, 2}). In contrast, a function
    returning the concrete type cannot be used in when a function returning the
    interface type is expected: If I have

    func GetRationalNumber() *Rational {
    return &Rational{1, 2}
    }

    func ThisDoesNotWork(fn func() Number) {
    x := fn()
    fmt.Println(x.Value())
    }


    then I cannot use ThisDoesNotWork(GetRationalNumber). Code to play with is
    here: http://play.golang.org/p/wpWAOaD4QT

    My question: Why does this not work? Is this something which may be changed
    in a future version of Go? Or is there a (technical or design) reason why a
    function returning a concrete type cannot be used in place of a function
    returning a compatible interface type?
    This has been discussed many times on the mailing list. Search for
    covariant types.

    Two very short answers are: 1) supporting only type equality in
    parameters simplifies method matchines; 2) covariant types are
    probably impossible to implement in full generality without generating
    code at run time.

    Ian

    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Jochen Voss at Nov 8, 2015 at 7:28 pm
    Thanks, I'll take a look. (I hadn't heard the term "covariant types"
    before. )
    On Sun, 8 Nov 2015 19:24 Ian Lance Taylor wrote:
    On Sun, Nov 8, 2015 at 10:25 AM, Jochen Voss wrote:

    I have a question about interfaces: A concrete type which implements an
    interface can be used as a function argument, when the function expects the
    interface type. Example: If I have the following code,

    type Number interface {
    Value() float64
    }

    type Rational struct {
    Numerator, Denominator int
    }

    func ThisWorks(x Number) {
    fmt.Println(x.Value())
    }


    then I can call ThisWorks(&Rational{1, 2}). In contrast, a function
    returning the concrete type cannot be used in when a function returning the
    interface type is expected: If I have

    func GetRationalNumber() *Rational {
    return &Rational{1, 2}
    }

    func ThisDoesNotWork(fn func() Number) {
    x := fn()
    fmt.Println(x.Value())
    }


    then I cannot use ThisDoesNotWork(GetRationalNumber). Code to play with is
    here: http://play.golang.org/p/wpWAOaD4QT

    My question: Why does this not work? Is this something which may be changed
    in a future version of Go? Or is there a (technical or design) reason why a
    function returning a concrete type cannot be used in place of a function
    returning a compatible interface type?
    This has been discussed many times on the mailing list. Search for
    covariant types.

    Two very short answers are: 1) supporting only type equality in
    parameters simplifies method matchines; 2) covariant types are
    probably impossible to implement in full generality without generating
    code at run time.

    Ian
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.
  • Nate Finch at Nov 9, 2015 at 8:11 pm
    Read this, I hope it helps:

    https://npf.io/2014/05/intro-to-go-interfaces/

    On Sunday, November 8, 2015 at 1:25:46 PM UTC-5, Jochen Voss wrote:

    Dear all,

    I have a question about interfaces: A concrete type which implements an
    interface can be used as a function argument, when the function expects the
    interface type. Example: If I have the following code,

    type Number interface {
    Value() float64
    }

    type Rational struct {
    Numerator, Denominator int
    }

    func ThisWorks(x Number) {
    fmt.Println(x.Value())
    }


    then I can call ThisWorks(&Rational{1, 2}). In contrast, a function
    returning the concrete type cannot be used in when a function returning the
    interface type is expected: If I have

    func GetRationalNumber() *Rational {
    return &Rational{1, 2}
    }

    func ThisDoesNotWork(fn func() Number) {
    x := fn()
    fmt.Println(x.Value())
    }


    then I cannot use ThisDoesNotWork(GetRationalNumber). Code to play with
    is here: http://play.golang.org/p/wpWAOaD4QT

    My question: Why does this not work? Is this something which may be
    changed in a future version of Go? Or is there a (technical or design)
    reason why a function returning a concrete type cannot be used in place of
    a function returning a compatible interface type?

    Many thanks,
    Jochen

    PS.: I know that I could change GetRationalNumber to return type Number in
    the above example. My question is not about how to fix my code, but about
    why Go is the way it is in this regard.
    --
    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+unsubscribe@googlegroups.com.
    For more options, visit https://groups.google.com/d/optout.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 8, '15 at 6:25p
activeNov 9, '15 at 8:11p
posts6
users5
websitegolang.org

People

Translate

site design / logo © 2021 Grokbase