GraphCool doesn't have much documentation on Enums, so I am just posting my Enum info for those who could use it:
Enums are arguments of an object that can only have specified values. GraphCool also, to my knowledge, requires them to be defined with a default value.
An example Enum is (write them in the enums tab):
enum PublishersEnum {
PEARSON
WILEY
MCGRAWHILL
}
An example type with enum:
type Book {
...
publisher: PublishersEnum #defaultValue(value: PEARSON)
...
}
Recommendations/conventions:
Use all caps to help distinguish enum usage.
Name the enum with "Enum" in the name somewhere
Concerns:
I have not had good luck with the graph cool interface, when I try to migrate from a string to an enum, the migration value and such didn't work well, hopefully others will have better luck.
Related
I have database and JSON models which use struct field annotation for various purposes, namely specifying enumerations, which values are acceptable for validations, etc.
A database model example:
type QRCode struct {
Algorithm string `json:"algorithm" gorm:"type:enum('hmac-sha3-256-v1')" validate:"oneof=hmac-sha3-256-v1"`
PublicCode []byte `json:"token" gorm:"size:32" validate:"len=32"`
UserType string `json:"user_type" gorm:"type:enum('admin','member')" validate:"one_of=admin member"`
gorm.Model
}
So in this case, there are a few different constants:
public key size, which I have in constants.QRCodePublicCodeLength
algorithm, which I have in constants.QRCodeAlgorithmV1
user type, which I have in constants.UserTypeAdmin and constants.UserTypeMember
It would be very nice to be able to embed these constants in the field tags so that there is truly one source of truth for everything, but I don't know if this is possible in Go.
Can I use constants in struct field tag definitions?
Can I use constants in struct field tag definitions?
No, this is not possible.
I've condensed things down to where I have a Generic Adapter, which is stored in an enum, that is non-generic. This looks like:
enum Collective {
StateTable(Adapter<StateTable>),
TestMessage(Adapter<TestMessage>)
}
I have getters and setters for Adapter, and I've stored Collective values in vector. While I can use match, to crack things out, via the following, I'm wondering if there isn't a better way.
impl Collective {
fn get_id(&self) -> u128 {
match self {
ReceiverAdapters::StateTable(a) => a.get_id(),
ReceiverAdapters::TestMessage(a) => a.get_id(),
}
}
I've considered From, but not sure if that will help. I'm also concerned with maintenance, as the number of variants grows. Can anyone provide an alternate to match? Or is match, under the covers compiling down to near-zero code in this case?
I'm working on several web server projects in Go, and there is a common problem that I'm always facing. I know we can achieve something like polymorphism in Go with interfaces and methods, but many times I had a scenario that I needed polymorphism on some data-holder structs that (maybe) just had some common fields, and no methods at all.
For example consider a story writing platform, where each user can write short stories and novels:
type ShortStory struct {
Name string
ID int
Body string
}
type LongStory struct {
Name string
ID int
Chapters []string
}
Now I simply want to have a data layer function, say GetStories(), which fetches all stories written by a user from database.
func GetStories(id int) []SOME_TYPE {
...
}
There are really no methods that I want to have on my ShortStory and LongStory structs. I know I can add a dummy method and let them satisfy some Storier interface, then use that interface as return type. But since there is no method I would want on a data container model, adding a dummy method just for the language to enable a feature, seems like a poor design choice to me.
I can also make the function return []interface{}, but that's against the whole idea of "typed language" I believe.
Another way is to have two separate GetShortStories() and GetLongStories() methods, which return a slice of their own type. But at some point I would finally want to merge those two slices into one and there I would again need a []interface{}. Yes, I can return a JSON like:
{
"short_stories" : [...],
"long_stories" : [...]
}
But I want my json to be like:
[{...}, {...}, {...}]
And I wouldn't change my APIs because of a language's limits!
I'm not a pro in Go, so am I missing something here? Is there a Go-ish approach to this, or is it really bad language design on Golang's side?
If you cannot express what you want to do using the features of a language, you should first try to change the way you structure your program before blaming the language itself. There are concepts that cannot be expressed in Go but can be expressed well in other languages, and there are concepts you cannot express well in other languages but you can in Go. Change the way you solve the problem to effectively use the language.
One way you can address your problem is using a different type of struct:
type Story struct {
Name string
ID int
ShortBody string
Chapters []string
}
If the Chapters is empty, then it is a short story.
Another way:
type Story struct {
Name string
ID int
Content StoryContent
}
type StoryContent interface {
Type() string
}
type ShortStory interface {
StoryContent
Body() string
}
type LongStory interface {
StoryContent
Chapters() []string
}
etc.
In 'modern' C++ that suppports strongly typed enums: is the class keyword optional?
I saw code that defines enums like:
enum SomeEnum: unsigned int {
VAL1 = 0,
VAL2 = 1,
// ...
};
Is this a different thing, a sloppyness of the compiler (VS 2015 (MSVC 19)) or is the class keyword implicit if the enum is strongly typed?
The code in the question declares a normal unscoped enumeration, whose underlying type is however fixed. So it is different from enum class because it still does not introduce a scope for its enumerators.
Since c++11 even normal enums (which still exist) can accept an underlying type specification. See here.
enum-key attr(optional) identifier(optional) enum-base(optional)(C++11) { enumerator-list(optional) }
Emphasis mine
So it is a normal enum not a enum class but with a enum-base specification.
What you call "strongly typed enum" is really named scoped enumerations, and for those the class or struct keyword is mandatory.
Using the "inheritance" syntax is not part of scoped enumerations, they can be used for normal unscoped enumerations as well.
After diving into the docs I couldn't find the answer to my following question:
Is there any reason against using this for referring to the current object as in the following example?
type MyStruct struct {
someField string
}
func (this MyStruct) getSomeField() string {
return this.someField
}
There is no technical reason not to do this.
It does go against the general guidelines as explained here:
Don't use generic names such as "me", "this" or "self", identifiers typical of object-oriented languages that place more emphasis on methods as opposed to functions.
I would also like to add that in languages that use this (or self), this is always a pointer. For method receivers in Go, this is not necessarily the case.