Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

When inheriting an interface, using the value same name and type as the interface is also considered as feasible for its implementation. #34891

Closed
godcong opened this issue Oct 14, 2019 · 3 comments

Comments

@godcong
Copy link

godcong commented Oct 14, 2019

What version of Go are you using (go version)?

go 1.13

Does this issue reproduce with the latest release?

yes

What did you do?

//Model is associated with the database
type Model struct {
	ID        string     
	CreatedAt time.Time 
	UpdatedAt time.Time
	DeletedAt *time.Time
	Version   int
}

type Modeler interface{
        ID() string
	SetID(string)
	Version() int
	SetVersion(int)
}

func SomeFunctionUseModeler(Modeler)

when the SomeFunctionUseModeler wants to use the Modeler interface.

In other languages,
We can use model if it implements the Modeler interface.
But in go, we can't do this.
Because the Model does not implement all the interfaces of the Modeler
If you want to use Model as Modeler,
You must change your ID and Version to other name.

The interface is widely used.
I think it should be more fault tolerant.
so if inheriting an interface,
If you use the same name and type of value as the interface, it is also considered to be its implementation.
Is it better?

@beoran
Copy link

beoran commented Oct 14, 2019

I woud solve this like problem this:

https://play.golang.org/p/gCwlNRZlR47

package main

import (
	"fmt"
	"time"
)


//Model is associated with the database
type Model struct {
	ID        string     
	CreatedAt time.Time 
	UpdatedAt time.Time
	DeletedAt *time.Time
	Version   int
}

type ModelModeler struct {  
	Model	
}

func (m ModelModeler) ID() string {
	return m.Model.ID
}

func (m ModelModeler) Version() int {
	return m.Model.Version
}

func (m ModelModeler) SetID(s string) {
	m.Model.ID = s
}

func (m ModelModeler) SetVersion(i int) {
	m.Model.Version = i
}

type Modeler interface{
        ID() string
	SetID(string)
	Version() int
	SetVersion(int)
}

func SomeFunctionUseModeler(m Modeler) {
  	fmt.Printf("Model: %s %d\n", m.ID(), m.Version())
}

func main() {
	m := ModelModeler{ Model: Model{ "Z80", time.Now(), time.Now(), nil, 1}}
	SomeFunctionUseModeler(m) 
}

If you find it a lot of work to write the ModelModeler struct and methods, it's quite easy to write a code generator with 'go/ast' and go generate that will do it for you.

@ianlancetaylor
Copy link
Contributor

I'm not sure, but I think you are suggesting that if a struct field is named F with type T, then it should automatically satisfy an interface with a method F() T. If you want to write that up as a language change proposal, please see https://golang.org/s/proposal. But I don't think such a change is particularly likely to be accepted. Any type can have methods, so why should struct types be special in this way? Also, in general interfaces describe behavior, but a field is just data. And, of course, people will immediately want some way to change the field, not just fetch it.

I'm going to close this issue, but please feel free to open a language change proposal.

If you just want to ask about how Go works, please see https://golang.org/wiki/Questions.

@godcong
Copy link
Author

godcong commented Oct 15, 2019

@beoran thanks for your response.
Although there is more structure, but it can solve this problem.
@ianlancetaylor
i only want to solve this problem.
beoran's response helps me.

@golang golang locked and limited conversation to collaborators Oct 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants