如何创建具有所需类型而不是类型断言的变量

I have a function which takes an interface, like this:

func method(data interface{})

.. because I need to process different structs which have common fields/methods. In this function I use data tens or hundreds of times, in different places. It's really unpleasant to add switch a.(type) { case .. case .. all the time.

Is there a way to create a variable with just one switch with needed type and then just use this variable everywhere later? Something like:

var a .... // something here

switch data.(type) {
case *Struct1:
    a = data.(*Struct1)
case *Struct2:
    a = data.(*Struct2)
}

// Continue with 'a' only
a.Param = 15
fmt.Println(a.String())

Go is a statically typed language, the type of a must be known at compile time. And since Go does not support generics yet, you can't do what you want.

Try to come up with some other solution, e.g. abstract away the things you want to do with a into an interface, and have the concrete types implement that interface. Then a can be a variable of this interface type, and you can call methods of it.

If you can achieve this, actually you can even change the parameter of the data type to this interface, and no type assertion or type switch is needed.

Alternatively you could use reflection to access common fields (either for get or set) identified by their name, but reflection provides no compile-time guarantee, and it's usually less efficient. For an example how to do that, see this question: Assert interface to its type

You can't do what you ask for in your question directly, go is statically typed, so you can't have one variable that can hold different types, and still access that variable as if it is typed.

If you're only working on the common struct fields in your method, you are perhaps better off gathering all the common variables in its own struct, illustrated below as the commons struct and have your method take that type as an argument

package main

import (
    "fmt"
)

type commons struct {
    name string
    age int
}
type structA struct {
    commons
    other_stuff int
}

type structB struct {
    commons
    foo string
}

func method(c* commons) {
    fmt.Println(c)
    c.age +=1

}
func main() {
    a := structA{commons{"foo", 44}, 1} 
    b := structB{commons{"bar", 33}, "test"} 
    method(&a.commons)
    method(&b.commons)
    fmt.Println(a)
}

Go playground

I can't figure out what is your real goal but if the "method" you want to write handles common fields from similar structures, and you cannot fix original structures using Type Embedding, as @nos said above, then you can try to make another structure for method-internal use:

var v Vehicle // with common fields

switch data.(type) {
case *Car:
    v.Handle = data.(*Car).Handle // or CircleHandle
case *Motorcycle:
    v.Handle = data.(*Motorcycle).Handle // or BarHandle
}

v.Degree = 15
v.Speed = 50
v.Direction = "left"
v.Style = "rough"
/// so many things on `v`...

steering(v)

I think it is not a good approach but sometimes... :-)