Which is the preferred way to declare a single constant in Go?
1)
const myConst
2)
const (
myConst
)
Both ways are accepted by gofmt. Both ways are found in stdlib, though 1) is used more.
The second form is mainly for grouping several constant declarations.
If you have only one constant, the first form is enough.
for instance archive/tar/reader.go:
const maxNanoSecondIntSize = 9
But in archive/zip/struct.go:
// Compression methods.
const (
Store uint16 = 0
Deflate uint16 = 8
)
That doesn't mean you have to group all constants in one const (): when you have constants initialized by iota (successive integer), each block counts.
See for instance cmd/yacc/yacc.go
// flags for state generation
const (
DONE = iota
MUSTDO
MUSTLOOKAHEAD
)
// flags for a rule having an action, and being reduced
const (
ACTFLAG = 1 << (iota + 2)
REDFLAG
)
dalu adds in the comments:
it can also be done with import, type, var, and more than once.
It is true, but you will find iota only use in a constant declaration, and that would force you to define multiple const () blocks if you need multiple sets of consecutive integer constants.
Related
Hello I am trying to make a byte slice with constants but I get the constant x overflows byte error.
Here are my constants:
const(
Starttrame1 = 0x10A
Starttrame2 = 0x10B
Starttrame3 = 0X10C
Starttrame4 = 0X10D
Starttrame5 = 0X10E
Starttrame6 = 0x10F
)
and here is how I declare my slice:
var startValues = [6]byte{Starttrame1,Starttrame2,Startrame3,Starttrame4,Starttrame5,Starttrame6}
Everytime I build I get the constant 266 overflows byte. How should I declare my constants in order to fix this?
In Go, byte is an alias for uint8, which is the set of all unsigned 8-bit integers (0..255, both inclusive), see Spec: Numeric types. Which means a value of 0x10A = 266 cannot be stored in a value of type byte.
If you need to store those constants, use a different type, e.g. uint16:
const (
Starttrame1 = 0x10A
Starttrame2 = 0x10B
Starttrame3 = 0X10C
Starttrame4 = 0X10D
Starttrame5 = 0X10E
Starttrame6 = 0x10F
)
var data = [...]uint16{
Starttrame1, Starttrame2, Starttrame3, Starttrame4, Starttrame5, Starttrame6,
}
Try it on the Go Playground.
I am trying to figure out how to initialize a variable in VBScript to its maximum value.
For example, in C++, I would do something like:
double x = MAX_DOUBLE;
I am not sure how to do this in VBScript.
UPDATE
For now, I have defined the variable myself as constant value in the global scope of the script. I am not sure if this is the most elegant way of doing this. Is there a built-in variable I can use?
Const MAX_DOUBLE = CDbl(1.79769313486232e307)
Const MIN_DOUBLE = CDbl(-1.79769313486232e307)
I've never found the limits described on MSDN to be accurate for many of the VBScript data types. For example, the Currency type gives me an overflow for anything > XXX.5625, even though the docs say it should go to XXX.5808. Same thing for Double. The docs say the max should be 1.79769313486232e308 but that final 2 in the mantissa causes an overflow. These are the values I've used in the past:
Const MIN_BYTE = 0
Const MAX_BYTE = 255
Const MIN_INTEGER = -32768
Const MAX_INTEGER = 32767
Const MIN_LONG = -2147483648
Const MAX_LONG = 2147483647
Const MIN_SINGLE = -3.402823e38
Const MAX_SINGLE = 3.402823e38
Const MIN_DOUBLE = -1.79769313486231e308
Const MAX_DOUBLE = 1.79769313486231e308
Const MIN_CURRENCY = -922337203685477.5625
Const MAX_CURRENCY = 922337203685477.5625
Const MIN_DATE = #100/1/1#
Const MAX_DATE = #9999/12/31#
Because VBScript uses Variants, however, note that you may not get the type you expect when assigning a "max" (or min) value to a variable. For example:
b = MAX_BYTE ' Actually type Integer
s = MAX_SINGLE ' Actually type Double
c = MAX_CURRENCY ' Actually type Double
If you want to ensure you're getting the proper data type in return, you'll need to explicitly cast:
b = CByte(MAX_BYTE) ' Type Byte
s = CSng(MAX_SINGLE) ' Type Single
c = CCur(MAX_CURRENCY) ' Type Currency
I understand that the idiomatic way to create an enum in GO is as follows:
type topicStatus int
const (
registered topicStatus = iota
active
inactive
pending-removal
removed
)
but if I have another "enum" that wants to "reuse" a name, I get an error:
type hotelVisit int
const (
registered hotelVisit = iota
checked-in
checked-out
)
Here, if I try this, I cannot differentiate between topicStatus.registered and hotelVisit.registered as "registered" was previously used - is there a way to "namespace" the "enum" names?
Polluting the namespace with numerous common word lower case identifiers that are likely to cause naming conflicts isn't something I'd consider idiomatic Go. Same goes for creating packages just to hold a handful of constant declarations.
I'd probably do something like this:
type topicStatus int
const (
tsRegistered topicStatus = iota
tsActive
tsInactive
tsPendingRemoval
tsRemoved
)
type hotelVisit int
const (
hvRegistered hotelVisit = iota
hvCheckedIn
hvCheckedOut
)
Now you can declare and initialize with ts := tsPendingRemoval. Clear and concise with little risk of naming conflicts.
One workaround is to use an anonymous struct to define a namespace.
type TopicStatusType int
const (
registered topicStatus = iota
active
...
)
var TopicStatus = struct{
Registered TopicStatusType
Active TopicStatusType
...
}{
Registered: registered,
Active: active,
...
}
Create a new package for each of the enums you want to define. This means creating a sub-directory with a go file the has "package topicStatus" with the const definition inside (sub-directory name is the same as the package name).
Remember all the constants defined must be upper case so they are exportable.
Do the same for "hotelVisit" and whatever you need.
Your program will import these packages and then use them as needed: hotelVisit.Registered, topicStatus.Registered.
You can do like this:
var JobRunPhaseConstants = struct {
QUEUE_PRE_EXEC int
JOB_PRE_EXEC int
JOB_RUN int
JOB_POST_EXEC int
QUEUE_POST_EXEC int
}{
QUEUE_PRE_EXEC: 1,
JOB_PRE_EXEC: 2,
JOB_RUN: 3,
JOB_POST_EXEC: 4,
QUEUE_POST_EXEC: 5,
}
// usage example
var a = JobRunPhaseConstants.JOB_RUN
Our game engine uses STL sort for sorting a whole range of different objects using the template sort function. As I understand the requirements for the comparison logic is that you have to write it on the basis that it may internally do a reverse sort ( ie reverse the pairing eg. from (a,b) to (b,a) ).
So typically my compare functions looks like this:
bool CompareSubGroupReqsByDescendingFillPriority::operator()
( const ScenSubGroupReq& lhs,
const ScenSubGroupReq& rhs ) const
{
if( lhs.mFillPriority > rhs.mFillPriority ) return true;
else if( lhs.mFillPriority < rhs.mFillPriority ) return false;
else return lhs.mForceGroup->ObjectID() > rhs.mForceGroup->ObjectID();
}
I refer to the "else" statement as the "deal breaker" - ie. it must be able to resolve a case where both lhs and rhs are the same. I typically use the object ID where we are sorting persistent objects.
My question is how can you create a deal breaker when you are sorting non-persistent objects that are simple data types (eg shorts)?
Here is the example I am wrestling with:
bool
ComparePhaseLineIndexesByAscendingValue::operator() ( const short lhs,
const short rhs ) const
{
if( lhs < rhs ) return true;
else if( lhs > rhs ) return false;
else
{
// should never be here as no two phase lines should have the same index
FPAssert( false );
return false;
}
}
Trouble is I have been testing this and found a valid case where where I can have two phase lines with the same index. I don't care which of the entries with the same value ends up first.
What would you advise?
Technically the sort function takes the less than operator. What you are trying to do seems to have something to do with making sure that even equal objects are returned in a specific order. Generally you would just do
bool
ComparePhaseLineIndexesByAscendingValue::operator() ( const short lhs,
const short rhs ) const
{
return lhs < rhs;
}
Though generally a comparison function isn't required for builtin types (I think it's any type with a < operator specified).
What is preferred (or right) way to group large number of related constants in the Go language? For example C# and C++ both have enum for this.
const?
const (
pi = 3.14
foo = 42
bar = "hello"
)
There are two options, depending on how the constants will be used.
The first is to create a new type based on int, and declare your constants using this new type, e.g.:
type MyFlag int
const (
Foo MyFlag = 1
Bar
)
Foo and Bar will have type MyFlag. If you want to extract the int value back from a MyFlag, you need a type coersion:
var i int = int( Bar )
If this is inconvenient, use newacct's suggestion of a bare const block:
const (
Foo = 1
Bar = 2
)
Foo and Bar are perfect constants that can be assigned to int, float, etc.
This is covered in Effective Go in the Constants section. See also the discussion of the iota keyword for auto-assignment of values like C/C++.
My closest approach to enums is to declare constants as a type. At least you have some type-safety which is the major perk of an enum type.
type PoiType string
const (
Camping PoiType = "Camping"
Eatery PoiType = "Eatery"
Viewpoint PoiType = "Viewpoint"
)
It depends on what do you want to achieve by this grouping. Go allows grouping with the following braces syntax:
const (
c0 = 123
c1 = 67.23
c2 = "string"
)
Which just adds nice visual block for a programmer (editors allow to fold it), but does nothing for a compiler (you can not specify a name for a block).
The only thing that depends on this block is the iota constant declaration in Go (which is pretty handy for enums). It allows you to create auto increments easily (way more than just auto increments: more on this in the link).
For example this:
const (
c0 = 3 + 5 * iota
c1
c2
)
will create constants c0 = 3 (3 + 5 * 0), c1 = 8 (3 + 5 * 1) and c2 = 13 (3 + 5 * 2).