Upcasting/Downcasting in Go

2,046 views
Skip to first unread message

Haiyu Zhen

unread,
Nov 8, 2017, 4:44:36 PM11/8/17
to golang-nuts
As someone who is new to Golang world, I am confused with the following code.

As sample code shown, type S's "underlying" type is slice (in C++ jargon S is the derived class of slice), and if I pass a slice as S in function parameter, it works; but if I pass slice as S in function receiver, Go doesn't "downcast" it to S.
I do know that S and []int are treated as different types in Go, but as the append function shows, Go will "upcast" S to slice to use slice.append(). 

So when should I expect the type casting to work? Or or specific to the scenario, why it fails if I use slice as the function receiver for S?
 
package main
import (
"fmt"
)
type S []int
 
func (s S) testUnderlyingTypeAsReciever() {
fmt.Println("Hello, playground")
}
func testUnderlyingTypeAsParam(s S) {
fmt.Println("Hello, playground")
}
func main() {
d := []int{2}
s := S{}
s = append(s, 1) // use append function for slice
testUnderlyingTypeAsParam(d) // pass
d.testUnderlyingTypeAsReciever() // fail
}

Ian Lance Taylor

unread,
Nov 8, 2017, 5:48:32 PM11/8/17
to Haiyu Zhen, golang-nuts
When thinking about Go it's best to avoid concepts that do not apply,
like derived class, upcast, and downcast. You can't write
d.testUnderlyingTypeAsReceiver() because the method is only defined on
the type S, and d is type []int, not type S. Passing d to
testUnderlyingTypeAsParam works because a value of an unnamed type is
assignable to a value of a named type when the underlying type of the
named type is the same as the unnamed type. There is no upcasting or
downcasting involved. There is just simple assignment.

Ian

Konstantin Khomoutov

unread,
Nov 9, 2017, 6:26:37 AM11/9/17
to golang-nuts, Haiyu Zhen
On Wed, Nov 08, 2017 at 02:48:06PM -0800, Ian Lance Taylor wrote:

[...]
>> So when should I expect the type casting to work?
[...]
> When thinking about Go it's best to avoid concepts that do not apply,
> like derived class, upcast, and downcast. You can't write
> d.testUnderlyingTypeAsReceiver() because the method is only defined on
> the type S, and d is type []int, not type S. Passing d to
> testUnderlyingTypeAsParam works because a value of an unnamed type is
> assignable to a value of a named type when the underlying type of the
> named type is the same as the unnamed type. There is no upcasting or
> downcasting involved. There is just simple assignment.

Haiyu Zhen, please also note that there are no such thing as "type casting"
in Go: it only has "type conversions" and "type assertions" (which come in
several forms).

Mauricio Rojas

unread,
Nov 9, 2017, 11:22:30 AM11/9/17
to golang-nuts
Hi All,

(S(d)).testUnderlyingTypeReciever()

Regards
Reply all
Reply to author
Forward
0 new messages