How can I pass a struct to a function as parameter?
If you really want to send any struct in generically like it is written in your original question (an empty interface parameter) so that AnyStruct.SomeField and AnotherStruct.SomeField, or AnyOtherStruct.AnyField can be accessed, AFAIK the reflecton features of go are the way to go.
For example if you look at the JSON marshal function it accepts pretty much any struct as a ("v") parameter sent in to a function with an empty interface parameter. Then that marshal function ends up calling
e.reflectValue(reflect.ValueOf(v), opts)
But you are probably looking for something simple as the other answers have suggested, which would not need advanced reflection (a sort of generic way of programming)
However I post this answer in case other readers are interested in sending structs in generally without needing to know up front what the struct fields are.
The reason a JSON parser needs to generically access a struct is for convenience of the user defining any struct he wants, and then Go automagically figures out the struct and maps it to a JSON syntax. You could imagine 100's of different struct layouts that you just want to place into a text file, without knowing all your struct layouts upfront - the function can figure out it at run time, which is how reflection works (other languages call it run time type information, meta programming, and similar).
You're looking for;
func test(class MyClass) {
fmt.Println(class.Name)
}
As it stands the method recognizes class
as some object which implements the empty interface (meaning in that scope it's fields and methods are completely unknown) which is why you get the error.
Your other option is something like this;
func test(class interface{}) {
if c, ok := class.(MyClass); ok { // type assert on it
fmt.Println(c.Name)
}
}
But there is no reason to in your example. It only makes sense if you're going to do a type switch or have multiple code paths that do different things based on the actual type of class
.
Depending on your needs, you have (at least) two options:
- Method on the struct type
- Func that takes struct type as parameter
package main
import "fmt"
type MyClass struct {
Name string
}
func main() {
cls := MyClass{Name: "Jhon"}
// Both calls below produce same result
cls.StructMethod() // "Jhon"
FuncPassStruct(cls) // "Jhon"
}
// Method on struct type
func (class MyClass) StructMethod() {
fmt.Println(class.Name)
}
// Function that takes struct type as the parameter
func FuncPassStruct(class MyClass) {
fmt.Println(class.Name)
}
I'm sure others may provide some interface wizardry I'm forgetting.
Please take a look over the Debug ,Receive methods. It uses stuct user, with its methods. https://play.golang.org/p/E_WkLWGdeB
package main
import "fmt"
// user defines a user in the program.
type user struct {
name string
email string
status string
}
func debug(u user) {
fmt.Printf("%+v\n", u)
}
// notify implements a method with a value receiver.
func (u user) notify() {
fmt.Printf("User: Sending User Email To %s<%s>\n", u.name, u.email)
}
// changeEmail implements a method with a pointer receiver.
func (u *user) changeEmail(email string) {
u.email = email
}
func (u *user) changeName(name string) {
u.name = name
}
func (u *user) Send() {
u.notify()
}
// main is the entry point for the application.
func main() {
// Pointers of type user can also be used to methods
// declared with a value receiver.
john := &user{"John", "[email protected]", "enabled"}
john.changeName("John Smith")
john.changeEmail("[email protected]")
john.notify()
Receive(john)
debug(user{"Willy", "[email protected]", "enabled"})
}
func Receive(user interface {
changeName(s string)
changeEmail(s string)
Send()
}) {
user.changeName("Bill")
user.changeEmail("[email protected]")
user.Send()
}