how to constrain a type

98 views
Skip to first unread message

Mark

unread,
Aug 17, 2023, 8:44:10 AM8/17/23
to golang-nuts
Here's something that works but uses `any` which is too broad in scope:
```go
type Shape any // Want to constrain to BoxShape and LineShape only

type BaseShape struct {
X         int
Y         int
PenColor  color
PenWidth  int
FillColor color
}

type BoxShape struct {
BaseShape
Width  int
Height int
}

type LineShape struct {
BaseShape
X2 int
Y2 int
}

shapes := []*Shape{}
```
Is there a nice way to create a `Shape` type which will allow me to do `shapes := []*Shape{}` and that _also_ constrains the shapes to `BoxShape` and `LineShape`?

Brian Candler

unread,
Aug 17, 2023, 11:35:10 AM8/17/23
to golang-nuts
I'm not sure without knowing *how* you want to use []*Shape{}.  Perhaps you want Shape to be an interface?

type Shape interface {
    DrawMe()
}

type BoxShape struct ...
func (*BoxShape) DrawMe() { }

type LineShape struct ...
func (*LineShape) DrawMe() { }

shapes := []Shape{}

(Note that interfaces internally carry pointers, so you don't generally want to have pointers to interface types)

Mark

unread,
Aug 17, 2023, 11:48:28 AM8/17/23
to golang-nuts
Hi Brian,
Sorry for not being clearer. Ideally I don't want an interface: each Shape is essentially a store of different kinds of values so at some point I'm going to iterate over them and within that iterating use a type switch. This is because the shapes _don't_ know how to draw themselves but an external function that reads them will know.

Brian Candler

unread,
Aug 17, 2023, 11:53:03 AM8/17/23
to golang-nuts
Then make a dummy interface, with a method with a unique name that you never call.

Mark

unread,
Aug 17, 2023, 12:48:06 PM8/17/23
to golang-nuts
Oh of course, thanks for the reminder!
```go
type Shape interface {
Shape()

}

type BaseShape struct {
X         int
Y         int
PenColor  color
PenWidth  int
FillColor color
}

type BoxShape struct {
BaseShape
Width  int
Height int
}

func (me *BoxShape) Shape() {}


type LineShape struct {
BaseShape
X2 int
Y2 int
}

func (me *LineShape) Shape() {}

shapes := []Shape{}
```
Thank you again.
Reply all
Reply to author
Forward
0 new messages