Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Given Go is largely based on C, and structs in that language are defined like this:
struct Person{...}
Why do we have the extra word in Go?
type Person struct{...}
Why do we need to mention both type and struct? Seems a little verbose.
All top-level statements in Go begin with a keyword indicating the type of declaration: package, import, type, var, const, or func, per the Go specification. As to why those decisions were made, you would need to ask those who made them, i.e. the Go maintainers.
Because both type and struct are significant here. You are defining a type with a keyword type. Your type could be anything, all of the following are valid
type MyBool bool
type MyInt int
type StringList []string
type StringListPointer *StringList
And to define a type that contains more than one value, you use the struct keyword.
type MyStruct struct {
x MyInt
y StringList
next *MyStruct
}
And you could, technically, have a struct without defining a type. This is not used very often, but it does have its use cases where you only intend to use a particular struct once. This is valid.
x := struct {
Name string
Value int
}{"Hello World!", 10}
fmt.Printf("%+v\n", x)
Consistency. The type keyword is used in all type definitions, and a defined type's underlying type needs not be a struct. Example:
type Fahrenheit int
Why would the language's designers make an exception for structs in Go's syntax?
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 months ago.
Improve this question
I want to include different structure pointer fields in the map as shown below. (Of course the code below doesnt work)
type StructA struct {
}
type StructB struct {
}
mymap := map[string]*struct{}{
"StructA": StructA,
"StructB": StructB,
}
As #icza said the element type of a map must be a specific type. But this could be an interface that can store an object of different types. The type any (an alias for interface{} is in some ways like a pointer (though it also stores type info), so you could just do:
mymap := map[string]inteface{}{
"StructA": StructA{},
"StructB": StructB{},
}
To be a little safer you can restrict the types that can be added to the map to just the two structs. To do this you need an interface which specifies a function that both the struct types implement.
type (
Common interface{ ImplementsCommon() }
A struct{}
B struct{}
)
func (A) ImplementsCommon() {}
func (B) ImplementsCommon() {}
mymap := map[string]Common{
"A": A{},
"B": B{},
}
Try it on the Go Playground
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
As we know, we can declare all type of map and slice,like []string, []int, []interface{}
This is already some kind of Generic.
I wonder how it implements?
Is it just like interface{}, storing type and value, like using void* to implement Generic in c language?
Found related explanation in Gopher Academy youtube channel, Keith Randall explaining about maps and how it is implemented to have many types without generics.
video link - Keith Randall - Inside the Map Implementation
As it is described and you can see in src/runtime/type.go Type informations are handled by this _type.
type _type struct {
size uintptr
ptrdata uintptr // size of memory prefix holding all pointers
hash uint32
tflag tflag
align uint8
fieldAlign uint8
kind uint8
// function for comparing objects of this type
// (ptr to object A, ptr to object B) -> ==?
equal func(unsafe.Pointer, unsafe.Pointer) bool
// gcdata stores the GC type data for the garbage collector.
// If the KindGCProg bit is set in kind, gcdata is a GC program.
// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
gcdata *byte
str nameOff
ptrToThis typeOff
}
*_type is using to describe key and element types in go maps, slices, arrays, channels.
ref := maptype, slicetype
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
Assume that I have a function that accepts a very broad interface, which could wrap(?) or describe many different types such as int64, float64, string, as well as other interfaces. However, this particular function only wants to interact with floats and ints, and will return an error for any other underlying concrete type.
What is an idiomatic way to do this in Go?
Should I use a switch statement and do nothing in the cases where it is int or float64 and return an error in the default case? This seems strange to me because those cases would just be empty.
e.g.
type BoardInterface interface{
doThing()
}
type customInt int
type customFloat float64
func (i customInt) doThing() {}
func (f customFloat) doThing() {}
// Other methods for different types here...
func getThing(i BoardInterface) error {
// i could be string, int, float, customInterface1, customInterface2...
// but we want to assert that it is int or float.
switch t := i.(type) {
case customInt:
// Do nothing here?
case customFloat:
// Do nothing here?
default:
return fmt.Errorf("Got %v want float or int", t)
}
// Do something with i here now that we know
// it is a float or int.
i.doThing()
return nil
}
Ideally your BoardInterface should incorporate all the behavior you want to use i for, and that way you can just "interact" with i via the methods listed in BoardInterface. That way it should not matter what concrete type is wrapped in i. If the compiler allowed to pass a value, you have guarantee it implements BoardInterface.
If for some reason that is not feasible (or not possible), your proposed solution is fine. You may simplify it by listing all allowed types in a simple case, and no need to declare t, you may use i just as well like this:
switch i.(type) {
case customInt, customFloat:
default:
return fmt.Errorf("Got %T want customInt or customFloat", i)
}
(Note I used %T in the error message, as that is more informative in this case.)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I have a program as below. I am trying to change the type of a function argument dynamically as another library I am using requires passing myMethod signature with concrete type instead of that interface to do proper unmarshalling. Is that even possible in Go to dynamically make a function or anonymous function with argument's type generated dynamically or perhaps change the parameter type of a function?
package main
import (
"fmt"
"reflect"
)
type MyType interface {
doThis()
}
type MyType1 struct{}
func (m MyType1) doThis() {
fmt.Println("Type1 doThis")
}
type MyType2 struct{}
func (m MyType2) doThis() {
fmt.Println("Type2 doThis")
}
func myMethod(myType MyType) {
myType.doThis()
}
func main() {
fmt.Println("Hello, playground")
var type1 MyType
type1 = &MyType1{}
type1Val := reflect.TypeOf(type1)
// TODO - change myMethod signature dynamically to accept type1Val as the type
}
Here is the GoPlay link
Edit: Adding clarification
The library I am using exposes a registerSomething(someFunc) where the input argument type of someFunc will be later used in some unmarshaling. If the input argument type is an interface, the unmarshal will return a map. If its a typed struct, the unmarshal will return the typed struct with all params populated correctly so I don't have to deal with unmarshaling.
How to change function parameter type dynamically in go [?]
You simply cannot. Go is statically typed.
(Making your code run is trivial, but probably not what you want:
type1Val := reflect.ValueOf(type1)
myMethod(*(type1Val.Interface().(*MyType1)))
and I have to admit I do not understand what you are trying to do with reflect here.)
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am working on a demo project to understand GO language. I have defined one interface and 2 struct type. Also, I have defined an array of interfaces. Depending on the user input, I define each element within the array as a type of struct. During the data manipulation, I want to check the type of the struct defined on the array.
I have tried to use reflect, but unfortunately it did not worked. Also other methods on internet did not worked. I received messages such as panic or json cannot Unmarshal.
type Main_interface interface {
}
type Struct1 struct {
Index int
ID int
Name string
}
type Struct2 struct {
Index int
Timestamp string
Temporary_ID int
}
var MyArray []Main_interface
//...
NewStruct1Block := generateStruct1Block(...)
MyArray = append(MyArray, NewStruct1Block)
//...
NewStruct2Block := generateStruct2Block(...)
MyArray = append(MyArray, NewStruct2Block)
UPDATE: I want to be able to check the kind of struct implements the interface at runtime, depending on the user input.
Your array can be heteregenious, that is, it can contain elements of different types. You can't ensure (at compile time) that all elements are of the same type.
That said, you can check a single element using the type cast syntax.
You have three options:
Option 1: Check against a specific type
var unknown Main_Interface = getSomethingSomewhere()
result, ok := unknown.(Struct1);
if ok {
// result has type `Struct1`
}
Option 2: Use a switch statement to cover multiple types (already presented in another answer)
switch t := unknown.(type) {
case Struct1:
// t has type `Struct1` within this block (at compile time)
case Struct2:
// t has type `Struct2` within this block (at compile time)
default:
// neither Struct1 no Struct2
}
Option 3: compare against another type at runtime.
Note that types returned by reflect.TypeOf are comparable using the == operator, as documented here:
https://golang.org/pkg/reflect/#Type
Type values are comparable, such as with the == operator, so they can be used as map keys. Two Type values are equal if they represent identical types.
So we can do something like this:
var s1 Struct1 // empty struct
var s2 Struct2 // empty struct
if reflect.TypeOf(unknown) == reflect.TypeOf(s1) {
// unknown holds an s1 instance
}
But this is obviously not useful when you can just do the compile time check. Instead, you can compare two unknowns to check if they are the same:
var unknown1 Main_Interface = getSomethingSomewhere()
var unknown2 Main_Interface = getSomethingSomewhereElse()
if reflect.TypeOf(unknown1) == reflect.TypeOf(unknown2) {
// they are the same type
}
You need to use type assestion as below:
var MyArray []Main_interface
NewStruct1Block := Struct1{}
NewStruct2Block := Struct2{}
MyArray = append(MyArray, NewStruct1Block)
MyArray = append(MyArray, NewStruct2Block)
fmt.Printf("%v", MyArray)
switch t := MyArray[0].(type) {
case Struct1:
fmt.Printf("%v", t)
t.ID = 1
case Struct2:
fmt.Printf("%v", t)
t.Timestamp = "A"
default:
fmt.Print("unknown")
}
Working code here:
https://play.golang.org/p/OhpBDJu_q2x