Reputation: 4688
I am having trouble in accessing the one struct's properties (named Params) in different file.
please consider x.go where i invoke a function(CreateTodo)
type Params struct {
Title string `json:"title"`
IsCompleted int `json:is_completed`
Status string `json:status`
}
var data = &Params{Title:"booking hotel", IsCompleted :0,Status:"not started"}
isCreated := todoModel.CreateTodo(data) // assume todoModel is imported
now CreateTodo is a method on a struct (named Todo) in different file lets say y.go
type Todo struct {
Id int `json:todo_id`
Title string `json:"title"`
IsCompleted int `json:is_completed`
Status string `json:status`
}
func (mytodo Todo)CreateTodo(data interface{}) bool{
// want to access the properties of data here
fmt.Println(data.Title)
return true
}
Now I just want to use properties of data in CreateTodo function in y.go. But i am not able to do so and getting following error
data.Title undefined (type interface {} is interface with no methods)
I am sure issue is around accepting struct as an empty interface but i am not able to figure out.
Please help here.Thanks
Upvotes: 3
Views: 1171
Reputation: 487705
If you want to operate on a Params
(or *Params
), you must do that.
If you want to operate on an opaque type hidden behind an interface{}
, you must do that.
In short, you cannot peek behind the curtain without peeking behind the curtain. Either expose the actual type Params
, so that you can look at it, or keep all the code that does look at it elsewhere. The "keep the code elsewhere" is where interface
really shines, because it allows you to declare that something otherwise-opaque has behaviors and ask for those behaviors to happen:
type Titler interface {
GetTitle() string
}
If Params
has a GetTitle
function, it becomes a Titler
.
You can now define your CreateTodo
as a function that takes a Titler
, and then you can pass &data
to this function.
This structure is overall quite klunky and it seems much more likely that Todo
itself should be an embeddable struct instead, but see a more complete example starting from a stripped-down version of your sample code here, in the Go Playground.
Upvotes: 0
Reputation: 4662
So you have one of two options, depending on your model:
Switch to data *Params
instead of data interface{}
as suggested in another answer but it looks like you are expecting different types in this function, if so; check option #2 below.
Use Type switches as follows:
func (t Todo) CreateTodo(data interface{}) bool {
switch x := data.(type) {
case Params:
fmt.Println(x.Title)
return true
// Other expected types
default:
// Unexpected type
return false
}
}
P.S. Be careful with your json
tags: it should be json:"tagName"
. Notice the ""
! Check go vet.
Upvotes: 2
Reputation: 200
You could just type the function parameter:
func (mytodo Todo)CreateTodo(data *Params) bool{
// want to access the properties of data here
fmt.Println(data.Title)
return true
}
See: https://play.golang.org/p/9N8ixBaSHdP
Upvotes: 0