Is it possible to create a function that only receives structs with a specific type of fields?

I have this function:

 func Action(dataStruct any) {
	[...]
}

I would like dataStruct to have only fields of this group of types [bool, string, int]

That means this struct is valid:

type CustomCase struct {
	Name string
	Cellphone int
	Alive bool
	Native bool
}

But this one is not because Names is a slice of strings:

type CustomCase struct {
	Names []string
	Cellphone int
	Alive bool
	Native bool
}

Currently I have it solved with reflect and checking each field, but if what I ask is possible then it would be great because if I code wrong I would have an error at compile time and not at run time how I am currently working.

If you write/generate a whole bunch of boilerplate for structs with every number of fields you need, with every struct field name you need, you can do it:

package main

type scalar interface {
	bool | int | string
}

type struct1[T0 scalar] interface {
	~struct{ a T0 } // note that field has to be named "a."
	// I can't get it to work without specifying the name.
}

type struct2[T0, T1 scalar] interface {
	~struct {
		a T0 // field must be named "a"
		b T1 // must be named "b"
	}
}

// you have to define a new struct3, struct4, etc.
// for every struct with every number of fields and every field name

type structs[T0, T1 scalar] interface {
	struct1[T0] | struct2[T0, T1]
	// you have to add a new Tn and structn[...] for every struct
}

func action[T structs[T0, T1], T0, T1 scalar](v T) {}

type OK0 struct{ a int }
type OK1 struct {
	a int
	b string
}

func main() {
	action[OK0, int, int](OK0{})
	action[OK1, int, string](OK1{})
}

but this seems completely impractical.

I would instead recommend using the go/* package(s) to scan through your source code and identify any structs that don’t meet that criteria.

This is not the solution I am looking for because the names are dynamic.

I figured. Like I said, It’s impractical. In that case, you could write your own “linter” to check for and detect this before you compile, but the Go compiler itself can’t check it.

Have you tried type assertion? Since you have the base struct hardcode (I guess), you can try and make a type assertion in Action and return if the struct is not the one you want.

No, because a struct can repeat several times the same type of field, it can have 3 bools and be valid, a type assertion must be exact and cannot be dynamized as already indicated.

Oh, sorry, I finally got it. That the structs are also have dynamically changing fields. Didn’t think about it at first

No, Go is not like, say, Javascript. A struct type has a set of fields fixed at compile time.

I know. That was a comment regarding the discussion

I think you would need to use reflection to inspect the fields inside the passed structure…

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.