Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions concepts/constants/.meta/config.json
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"
]
}
83 changes: 57 additions & 26 deletions concepts/constants/about.md
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
67 changes: 51 additions & 16 deletions concepts/constants/introduction.md
Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Member Author

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.

Copy link
Copy Markdown
Member

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.

Copy link
Copy Markdown
Member Author

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.

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.
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.

## 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 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.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Constants can only hold booleans, numbers, strings, and runes.
Constants can only hold Booleans, numbers, strings, and runes.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The 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)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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 bool data type that represents a Boolean value, similar to an int type that represents an integer. There is no "Integer" and there is no "boolean".

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.
Loading