0

For basic types we can easily cast the types if their underlying types are same .But the fields inside struct with same memory layout cannot be easily cast from one to another type. There is a proposal for this problem unfortunately it got rejected .After an hour of googling with no luck I came here seeking the help from experts.

Look at example below :

package main

import (
    "fmt"
)

type Int int

type A struct {
    name string
    age  Int
}
type B struct {
    name string
    age  int
}

func main() {
    var a A= A{"Foo",21}
    var b B= B{"Bar", 21}
    fmt.Println(a,b,(A)(b))  //Error here as expected
}

Eventhough struct A and B has the same underlying type of struct { string,int} why cannot I cast to each other as the underlying type of Int is int. Whether it is possible to cast recursively unless the underlying type differs?

3
  • 2
    There are no type casts in Go. You are talking about type conversions and this type of type conversion is simply dissalowed. Commented Dec 19, 2020 at 8:45
  • sorry for that.I am from oops background,that causes issues in naming conventions. Commented Dec 19, 2020 at 9:20
  • 2
    "Type casting" is not an OOP concept at all. In fact, it predates OOP by decades. It's also not a matter of naming conventions. It's a matter of functionality. "Type casing" describes a very specific behavior that Go does not support. Commented Dec 19, 2020 at 9:53

2 Answers 2

2

You can't do it simply because the language spec does not allow it. Regarding structs, you can only convert from one type to the other if Spec: Conversion:

A non-constant value x can be converted to type T in any of these cases:

If you're absolutely sure the structs' memory layout is identical, you may use an unsafe conversion (using package unsafe) like this:

var a A = A{"Foo", 21}
var b B

b = *(*B)(unsafe.Pointer(&a))
fmt.Println(a, b)

This will output (try it on the Go Playground):

{Foo 21} {Foo 21}

But use this as the last resort. Using unsafe you lose compile time type safety and portability guarantees. E.g. if later you only modify one of the structs, the above code will continue to compile even though it might not be correct anymore, and the compiler will not able to inform you about that.

Sign up to request clarification or add additional context in comments.

2 Comments

What about two maps which are similar to above case ie) map[int][string] and map[Int][string] ?
@chellathurai Maps are pointers in Go. How the values are hashed and used in its internal structure is implementation detail. Don't try to utilize this unsafe conversion. Try to avoid it.
1

The reason why this conversion isn't allowed in your program:

type A B   // this isn't a type alias

In this example A has the same binary structure as B. However A doesn't inherit any methods associated with B at all!

Let's assume this code:

func (b B) method()

The following would be valid

var b B
b.method()

This is INVALID

var a A
a.method() // for type A no method of name 'method' exists

The Spec assumes that A and B could be indeed very different. So no type conversion allowed.

You could use instead a type alias like that:

type Int = int

Here is a Playground link.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.