-
-
Notifications
You must be signed in to change notification settings - Fork 683
Update constants docs
#3058
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Update constants docs
#3058
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,9 @@ | ||
| { | ||
| "blurb": "Constants are pieces of data similar to variables, but whose value cannot change during execution.", | ||
| "authors": ["jamessouth"], | ||
| "contributors": [] | ||
| "blurb": "Constants are named values that don't change during a program's execution.", | ||
| "authors": [ | ||
| "jamessouth" | ||
| ], | ||
| "contributors": [ | ||
| "BNAndras" | ||
| ] | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,51 +1,82 @@ | ||
| # About | ||
|
|
||
| Constants in Go are simple, [unchanging values][const] created with the `const` keyword. | ||
| Constants may be given an explicit type: | ||
| Constants are values set at compile time and cannot be reassigned. | ||
| Use the `const` keyword to declare a single constant: | ||
|
|
||
| ```go | ||
| const hi string = "hi" // string | ||
| const greeting = "hello" | ||
| ``` | ||
|
|
||
| or an implicit, default type: | ||
| Multiple constants can be declared in a block. | ||
| Within a block, a constant without an explicit value set repeats the previous expression: | ||
|
|
||
| ```go | ||
| const hello = "hello" // string | ||
| const ( | ||
| greeting = "hello" | ||
| buffSize = 4096 | ||
| chunkSize // 4096 | ||
| ) | ||
| ``` | ||
|
|
||
| when the variable needs a type. | ||
| This gives constants more flexibility in Go's type system and allows them to work in a variety of contexts without triggering a compiler error: | ||
| Constants are typically declared at package level, though uncommonly they can also be declared inside a function. | ||
|
|
||
| ## Typed and untyped constants | ||
|
|
||
| Declaring a constant without specifying a type makes it untyped. | ||
| An untyped constant has no set type, but its value determines what types it's compatible with. | ||
| As long as the underlying value is compatible, the compiler will convert it to the required type at each use: | ||
|
|
||
| ```go | ||
| const number2 = 2 // 2 is an untyped numeric constant and does not need to be explicitly given the type float64 as required by the Sqrt method | ||
| sqrt2 := math.Sqrt(number2) | ||
| const numA = 2 | ||
|
|
||
| math.Sqrt(numA) // numA is treated as float64 here | ||
| var numB int = numA // numA is treated as int here | ||
| ``` | ||
|
|
||
| Go does not have enums like some other languages but the `iota` enumerator can be used to create successive untyped integer constants: | ||
| A typed constant fixes the type at declaration: | ||
|
|
||
| ```go | ||
| const num int = 2 | ||
|
|
||
| math.Sqrt(num) // compile error because a float is expected | ||
| ``` | ||
|
|
||
| ## What can be a constant | ||
|
|
||
| Constants can only hold booleans, numbers, strings, and runes. | ||
| Because the values are set at compile time, the results of a function call can not be constants: | ||
|
|
||
| ```go | ||
| const s = math.Sqrt(4) // compile error because the value isn't known at compile time | ||
| ``` | ||
|
|
||
| ## Iota | ||
|
|
||
| Within a block of constants, `iota` represents each constant's position within the block: | ||
|
|
||
| ```go | ||
| const ( | ||
| a = 6 * iota // 0 | ||
| b // 6 | ||
| c // 12 | ||
| d // 18 | ||
| Sunday = iota // 0 | ||
| Monday // 1 | ||
| Tuesday // 2 | ||
| Wednesday // 3 | ||
| ) | ||
| ``` | ||
|
|
||
| Complex types like maps and slices are mutable and cannot be constants; the compiler will throw errors: | ||
| Each constant after the first inherits the same expression, with `iota` incrementing by one. | ||
|
|
||
| `iota` also works in expressions. | ||
|
|
||
| ```go | ||
| func main() { | ||
| const m = map[int]int{2: 8} | ||
| const s = []string{"exercism", "v3"} | ||
| } | ||
| // => const initializer map[int]int literal is not a constant | ||
| // => const initializer []string literal is not a constant | ||
| const ( | ||
| _ = iota // position 0: value discarded | ||
| KB = 1 << (10 * iota) // position 1: 1 << 10 = 1024 | ||
| MB // position 2: 1 << 20 = 1048576 | ||
| GB // position 3: 1 << 30 = 1073741824 | ||
| ) | ||
| ``` | ||
|
|
||
| For a fuller explanation please see [Effective Go][const2], [The Go Blog][const3], and [YourBasic Go][const4]. | ||
| For a deeper look at constants in Go, see [The Go Blog][const-blog] and [Effective Go][effective-go]. | ||
|
|
||
| [const]: https://golang.org/ref/spec#Constants | ||
| [const2]: https://golang.org/doc/effective_go.html#constants | ||
| [const3]: https://blog.golang.org/constants | ||
| [const4]: https://yourbasic.org/golang/untyped-constants/ | ||
| [const-blog]: https://go.dev/blog/constants | ||
| [effective-go]: https://go.dev/doc/effective_go#constants |
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -1,31 +1,66 @@ | ||||||
| # Introduction | ||||||
|
|
||||||
| In Go, a constant is a simple, unchanging value assigned to a name with the `const` keyword: | ||||||
| Constants are values set at compile time and cannot be reassigned. | ||||||
BNAndras marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| Use the `const` keyword to declare a constant: | ||||||
|
|
||||||
| ```go | ||||||
| const myWebsite = "Exercism" | ||||||
| const greeting = "hello" | ||||||
| ``` | ||||||
|
|
||||||
| Such constants are untyped, but they are given a default type based on their syntax when a type is required, such as when they are passed to a method. | ||||||
| Typed constants can be created by explicitly adding a type: | ||||||
| Multiple constants can be declared in a block. | ||||||
| Within a block, a constant without an explicit value repeats the previous expression: | ||||||
|
|
||||||
| ```go | ||||||
| const myWebsite string = "Exercism" | ||||||
| const ( | ||||||
| greeting = "hello" | ||||||
| buffSize = 4096 | ||||||
| chunkSize // 4096 | ||||||
| ) | ||||||
| ``` | ||||||
|
|
||||||
| Go does not have enums like some other languages, but does have a predeclared identifier called `iota` for creating enumerated constants. | ||||||
| Constants in a block are implicitly repeated: | ||||||
| Constants are typically declared at package level, though uncommonly they can also be declared inside a function. | ||||||
BNAndras marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
|
|
||||||
| ## Typed and untyped constants | ||||||
|
|
||||||
| Declaring a constant without specifying a type makes it untyped. | ||||||
| An untyped constant has no set type, but its value determines what types it's compatible with. | ||||||
BNAndras marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| As long as the underlying value is compatible, the compiler will convert it to the required type at each use: | ||||||
|
|
||||||
| ```go | ||||||
| const numA = 2 | ||||||
|
|
||||||
| math.Sqrt(numA) // numA is treated as float64 here | ||||||
| var numB int = numA // numA is treated as int here | ||||||
| ``` | ||||||
|
|
||||||
| A typed constant fixes the type at declaration: | ||||||
|
|
||||||
| ```go | ||||||
| const num int = 2 | ||||||
|
|
||||||
| math.Sqrt(num) // compile error because a float is expected | ||||||
| ``` | ||||||
|
|
||||||
| ## What can be a constant | ||||||
|
|
||||||
| Constants can only hold booleans, numbers, strings, and runes. | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I’d agree since it’s named after a person, but Go uses booleans. We also use it lowercased in our docs (see https://exercism.org/tracks/go/concepts/booleans)
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think Bethany set me straight on this. Go (and Python) has a
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yep. I’m fine with the change. My thought was that this should also be updated across the track where relevant. That can happen before or after this is merged.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Definitely. Doing it as a separate PR might be cleaner. |
||||||
| Because the values are set at compile time, the results of a function call can not be constants: | ||||||
|
|
||||||
| ```go | ||||||
| const s = math.Sqrt(4) // compile error because the value isn't known at compile time | ||||||
| ``` | ||||||
|
|
||||||
| ## Iota | ||||||
|
|
||||||
| Within a block of constants, `iota` represents each constant's position within the block: | ||||||
|
|
||||||
| ```go | ||||||
| const ( | ||||||
| a = 9 | ||||||
| b | ||||||
| c | ||||||
| d = iota | ||||||
| e | ||||||
| f | ||||||
| g | ||||||
| Sunday = iota // 0 | ||||||
| Monday // 1 | ||||||
| Tuesday // 2 | ||||||
| Wednesday // 3 | ||||||
| ) | ||||||
| fmt.Print(a, b, c, d, e, f, g) | ||||||
| // Output: 9 9 9 3 4 5 6 | ||||||
| ``` | ||||||
|
|
||||||
| Each constant after the first inherits the same expression, with `iota` incrementing by one. | ||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a few differences between the intro and about. I'm not sure if those are intentional. If the two are fairly close, it might be worth making them the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’d rather have different content for the two files, but the overlap is fairly significant here. We might as well make them the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm all for making them different ... where there's a value to that difference, eg omitting some sections from the intro to make it simpler. But if the content is largely the same, there's no reason not to make them entirely the same.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I’ll update the docs Monday.