mirror of
https://github.com/bootdotdev/fcc-learn-golang-assets.git
synced 2025-12-14 09:11:16 +00:00
first
This commit is contained in:
9
course/2-variables/exercises/1-basic_types/code.go
Normal file
9
course/2-variables/exercises/1-basic_types/code.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// initialize variables here
|
||||
|
||||
fmt.Printf("%v %f %v %q\n", smsSendingLimit, costPerSMS, hasPermission, username)
|
||||
}
|
||||
11
course/2-variables/exercises/1-basic_types/complete.go
Normal file
11
course/2-variables/exercises/1-basic_types/complete.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
var smsSendingLimit int
|
||||
var costPerSMS float64
|
||||
var hasPermission bool
|
||||
var username string
|
||||
fmt.Printf("%v %f %v %q\n", smsSendingLimit, costPerSMS, hasPermission, username)
|
||||
}
|
||||
1
course/2-variables/exercises/1-basic_types/expected.txt
Normal file
1
course/2-variables/exercises/1-basic_types/expected.txt
Normal file
@@ -0,0 +1 @@
|
||||
0 0.000000 false ""
|
||||
43
course/2-variables/exercises/1-basic_types/readme.md
Normal file
43
course/2-variables/exercises/1-basic_types/readme.md
Normal file
@@ -0,0 +1,43 @@
|
||||
# Basic Types
|
||||
|
||||
Go's basic variable types are:
|
||||
|
||||
```go
|
||||
bool
|
||||
|
||||
string
|
||||
|
||||
int int8 int16 int32 int64
|
||||
uint uint8 uint16 uint32 uint64 uintptr
|
||||
|
||||
byte // alias for uint8
|
||||
|
||||
rune // alias for int32
|
||||
// represents a Unicode code point
|
||||
|
||||
float32 float64
|
||||
|
||||
complex64 complex128
|
||||
```
|
||||
|
||||
We talked about `string`s and `int`s previously, and those two types should be fairly self-explanatory. A `bool` is a boolean variable, meaning it has a value of `true` or `false`. The [floating point](https://en.wikipedia.org/wiki/Floating-point_arithmetic) types (`float32` and `float64`) are used for numbers that are not integers -- that is, they have digits to the right of the decimal place, such as `3.14159`. The `float32` type uses 32 bits of precision, while the `float64` type uses 64 bits to be able to more precisely store more digits. Don't worry too much about the intricacies of the other types for now. We will cover some of them in more detail as the course progresses.
|
||||
|
||||
# Declaring a variable
|
||||
|
||||
Variables are declared using the `var` keyword. For example, to declare a variable called `number` of type `int`, you would write:
|
||||
|
||||
```go
|
||||
var number int
|
||||
```
|
||||
|
||||
To declare a variable called `pi` to be of type `float64` with a value of `3.14159`, you would write:
|
||||
|
||||
```go
|
||||
var pi float64 = 3.14159
|
||||
```
|
||||
|
||||
The value of an initialized variable with no assignment will be its [zero value](https://tour.golang.org/basics/12).
|
||||
|
||||
## Initialize some variables
|
||||
|
||||
Initialize the given variables to `int`, `float64`, `bool` and `string` respectively, with their zero values.
|
||||
17
course/2-variables/exercises/10-conditionals/code.go
Normal file
17
course/2-variables/exercises/10-conditionals/code.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
messageLen := 10
|
||||
maxMessageLen := 20
|
||||
fmt.Println("Trying to send a message of length:", messageLen, "and a max length of:", maxMessageLen)
|
||||
|
||||
// don't touch above this line
|
||||
|
||||
if messageLen > maxMessageLen {
|
||||
fmt.Println("Message sent")
|
||||
} else {
|
||||
fmt.Println("Message not sent")
|
||||
}
|
||||
}
|
||||
17
course/2-variables/exercises/10-conditionals/complete.go
Normal file
17
course/2-variables/exercises/10-conditionals/complete.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
messageLen := 10
|
||||
maxMessageLen := 20
|
||||
fmt.Println("Trying to send a message of length:", messageLen, "and a max length of:", maxMessageLen)
|
||||
|
||||
// don't touch above this line
|
||||
|
||||
if messageLen <= maxMessageLen {
|
||||
fmt.Println("Message sent")
|
||||
} else {
|
||||
fmt.Println("Message not sent")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
Trying to send a message of length: 10 and a max length of: 20
|
||||
Message sent
|
||||
36
course/2-variables/exercises/10-conditionals/readme.md
Normal file
36
course/2-variables/exercises/10-conditionals/readme.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Conditionals
|
||||
|
||||
`if` statements in Go don't use parentheses around the condition:
|
||||
|
||||
```go
|
||||
if height > 4 {
|
||||
fmt.Println("You are tall enough!")
|
||||
}
|
||||
```
|
||||
|
||||
`else if` and `else` are supported as you would expect:
|
||||
|
||||
```go
|
||||
if height > 6 {
|
||||
fmt.Println("You are super tall!")
|
||||
} else if height > 4 {
|
||||
fmt.Println("You are tall enough!")
|
||||
} else {
|
||||
fmt.Println("You are not tall enough!")
|
||||
}
|
||||
```
|
||||
|
||||
## Assignment
|
||||
|
||||
Fix the bug on line `12`. The `if` statement should print "Message sent" if the `messageLen` is *less than or equal to* the `maxMessageLen`, or "Message not sent" otherwise.
|
||||
|
||||
### Tips
|
||||
|
||||
Here are some of the comparison operators in Go:
|
||||
|
||||
* `==` equal to
|
||||
* `!=` not equal to
|
||||
* `<` less than
|
||||
* `>` greater than
|
||||
* `<=` less than or equal to
|
||||
* `>=` greater than or equal to
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"question": "Why would you use the 'initial' section of an `if` statement?",
|
||||
"answers": [
|
||||
"To keep the code concise and the scope limited",
|
||||
"To speed up my code",
|
||||
"To confuse other programmers"
|
||||
]
|
||||
}
|
||||
29
course/2-variables/exercises/11-if_init/readme.md
Normal file
29
course/2-variables/exercises/11-if_init/readme.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# The initial statement of an if block
|
||||
|
||||
An `if` conditional can have an "initial" statement. The variable(s) created in the initial statement are *only* defined within the scope of the `if` body.
|
||||
|
||||
```go
|
||||
if INITIAL_STATEMENT; CONDITION {
|
||||
}
|
||||
```
|
||||
|
||||
## Why would I use this?
|
||||
|
||||
This is just some syntactic sugar that Go offers to shorten up code in some cases. For example, instead of writing:
|
||||
|
||||
```go
|
||||
length := getLength(email)
|
||||
if length < 1 {
|
||||
fmt.Println("Email is invalid")
|
||||
}
|
||||
```
|
||||
|
||||
We can do:
|
||||
|
||||
```go
|
||||
if length := getLength(email); length < 1 {
|
||||
fmt.Println("Email is invalid")
|
||||
}
|
||||
```
|
||||
|
||||
Not only is this code a bit shorter, but it also removes `length` from the parent scope, which is convenient because we don't need it there - we only need access to it while checking a condition.
|
||||
@@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// declare here
|
||||
|
||||
fmt.Println(congrats)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// declare here
|
||||
congrats := "happy birthday!"
|
||||
|
||||
fmt.Println(congrats)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
happy birthday!
|
||||
30
course/2-variables/exercises/2-short_declarations/readme.md
Normal file
30
course/2-variables/exercises/2-short_declarations/readme.md
Normal file
@@ -0,0 +1,30 @@
|
||||
# Short Variable Declaration
|
||||
|
||||
Inside a function (even the main function), the `:=` short assignment statement can be used in place of a `var` declaration. The `:=` operator infers the type of the new variable based on the value.
|
||||
|
||||
```go
|
||||
var empty string
|
||||
```
|
||||
|
||||
Is the same as
|
||||
|
||||
|
||||
```go
|
||||
empty := ""
|
||||
```
|
||||
|
||||
```go
|
||||
numCars := 10 // inferred to be an integer
|
||||
|
||||
temperature := 0.0 // temperature is inferred to be a floating point value because it has a decimal point
|
||||
|
||||
var isFunny = true // isFunny is inferred to be a boolean
|
||||
```
|
||||
|
||||
Outside of a function (in the [global/package scope](https://dave.cheney.net/2017/06/11/go-without-package-scoped-variables)), every statement begins with a keyword (`var`, `func`, and so on) and so the `:=` construct is not available.
|
||||
|
||||
## Assignment
|
||||
|
||||
A lot of our users send birthday messages using the Textio API.
|
||||
|
||||
Declare a variable named `congrats` with the value "happy birthday!" using a short variable declaration.
|
||||
8
course/2-variables/exercises/3-type_inference/code.go
Normal file
8
course/2-variables/exercises/3-type_inference/code.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
penniesPerText := 2
|
||||
fmt.Printf("The type of penniesPerText is %T\n", penniesPerText)
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
penniesPerText := 0.02
|
||||
fmt.Printf("The type of penniesPerText is %T\n", penniesPerText)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
The type of penniesPerText is float64
|
||||
24
course/2-variables/exercises/3-type_inference/readme.md
Normal file
24
course/2-variables/exercises/3-type_inference/readme.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# Type Inference
|
||||
|
||||
To declare a variable without specifying an explicit type (either by using the `:=` syntax or `var = expression` syntax), the variable's type is *inferred* from the value on the right hand side.
|
||||
|
||||
When the right hand side of the declaration is typed, the new variable is of that same type:
|
||||
|
||||
```go
|
||||
var i int
|
||||
j := i // j is also an int
|
||||
```
|
||||
|
||||
However, when the right hand side is a literal value (an untyped numeric constant like `42` or `3.14`), the new variable will be an `int`, `float64`, or `complex128` depending on its precision:
|
||||
|
||||
```go
|
||||
i := 42 // int
|
||||
f := 3.14 // float64
|
||||
g := 0.867 + 0.5i // complex128
|
||||
```
|
||||
|
||||
## Assignment
|
||||
|
||||
Our current price to send a text message is 2 cents. However, it's likely that in the future the price will be a fraction of a penny, so we should use a `float64` to store this value.
|
||||
|
||||
Edit the `penniesPerText` declaration so that it's inferred by the compiler to be a `float64`.
|
||||
@@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// declare here
|
||||
|
||||
fmt.Println(averageOpenRate, displayMessage)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
// declare here
|
||||
averageOpenRate, displayMessage := .23, "is the average open rate of your messages"
|
||||
fmt.Println(averageOpenRate, displayMessage)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
0.23 is the average open rate of your messages
|
||||
@@ -0,0 +1,17 @@
|
||||
# Same Line Declarations
|
||||
|
||||
We are able to declare multiple variables on the same line:
|
||||
|
||||
```go
|
||||
mileage, company := 80276, "Tesla"
|
||||
|
||||
// is the same as
|
||||
|
||||
mileage := 80276
|
||||
company := "Tesla"
|
||||
```
|
||||
## Assignment
|
||||
|
||||
Within the main function, declare a float called `averageOpenRate` and string called `displayMessage` on the same line.
|
||||
|
||||
Initialize them to values of `.23` and `is the average open rate of your messages` respectively before they are printed.
|
||||
12
course/2-variables/exercises/5-type_sizes/code.go
Normal file
12
course/2-variables/exercises/5-type_sizes/code.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
accountAge := 2.6
|
||||
|
||||
// create a new "accountAgeInt" here
|
||||
// it should be the result of casting "accountAge" to an integer
|
||||
|
||||
fmt.Println("Your account has existed for", accountAgeInt, "years")
|
||||
}
|
||||
13
course/2-variables/exercises/5-type_sizes/complete.go
Normal file
13
course/2-variables/exercises/5-type_sizes/complete.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
accountAge := 2.6
|
||||
|
||||
// create a new "accountAgeInt" here
|
||||
// it should be the result of casting "accountAge" to an integer
|
||||
accountAgeInt := int(accountAge)
|
||||
|
||||
fmt.Println("Your account has existed for", accountAgeInt, "years")
|
||||
}
|
||||
1
course/2-variables/exercises/5-type_sizes/expected.txt
Normal file
1
course/2-variables/exercises/5-type_sizes/expected.txt
Normal file
@@ -0,0 +1 @@
|
||||
Your account has existed for 2 years
|
||||
37
course/2-variables/exercises/5-type_sizes/readme.md
Normal file
37
course/2-variables/exercises/5-type_sizes/readme.md
Normal file
@@ -0,0 +1,37 @@
|
||||
# Type Sizes
|
||||
|
||||
Ints, [uints](https://www.cs.utah.edu/~germain/PPS/Topics/unsigned_integer.html#:~:text=Unsigned%20Integers,negative%20(zero%20or%20positive).), [floats](https://techterms.com/definition/floatingpoint), and [complex](https://www.cloudhadoop.com/2018/12/golang-tutorials-complex-types-numbers.html#:~:text=Golang%20Complex%20Type%20Numbers,complex%20number%20is%2012.8i.) numbers all have type sizes.
|
||||
|
||||
```go
|
||||
int int8 int16 int32 int64 // whole numbers
|
||||
|
||||
uint uint8 uint16 uint32 uint64 uintptr // positive whole numbers
|
||||
|
||||
float32 float64 // decimal numbers
|
||||
|
||||
complex64 complex128 // imaginary numbers (rare)
|
||||
```
|
||||
|
||||
The size (8, 16, 32, 64, 128, etc) indicates how many bits in memory will be used to store the variable. The default `int` and `uint` types are just aliases that refer to their respective 32 or 64 bit sizes depending on the environment of the user.
|
||||
|
||||
The standard sizes that should be used unless the developer has a specific need are:
|
||||
|
||||
* `int`
|
||||
* `uint`
|
||||
* `float64`
|
||||
* `complex128`
|
||||
|
||||
Some types can be converted the following way:
|
||||
|
||||
```go
|
||||
temperatureInt := 88
|
||||
temperatureFloat := float64(temperatureInt)
|
||||
```
|
||||
|
||||
Casting a float to an integer in this way [truncates](https://techterms.com/definition/truncate) the floating point portion.
|
||||
|
||||
## Assignment
|
||||
|
||||
Our Textio customers want to know how long they have had accounts with us.
|
||||
|
||||
Follow the instructions in the comment provided. You will create a new variable called `accountAgeInt` that will be the truncated, integer version of `accountAge`.
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"question": "When should you elect to NOT use a 'default type'?",
|
||||
"answers": [
|
||||
"When performance and memory are the primary concern",
|
||||
"When my system has lots of extra hardware I want to utilize",
|
||||
"When either a 'default' or a specific size will work"
|
||||
]
|
||||
}
|
||||
28
course/2-variables/exercises/6-which_type_to_use/readme.md
Normal file
28
course/2-variables/exercises/6-which_type_to_use/readme.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Which Type Should I Use?
|
||||
|
||||
With so many types for what is essentially just a number, developers coming from languages that only have one kind of `Number` type (like JavaScript) may find the choices daunting.
|
||||
|
||||
## Prefer "default" types
|
||||
|
||||
A problem arises when we have a `uint16`, and the function we are trying to pass it into takes an `int`. We're forced to write code riddled with type casts like `int(myUint16)`.
|
||||
|
||||
This style of development can be slow and annoying to read. When Go developers stray from the “default” type for any given type family, the code can get messy quickly.
|
||||
|
||||
Unless you have a good reason to, stick to the following types:
|
||||
|
||||
* `bool`
|
||||
* `string`
|
||||
* `int`
|
||||
* `uint32`
|
||||
* `byte`
|
||||
* `rune`
|
||||
* `float64`
|
||||
* `complex128`
|
||||
|
||||
## When should I use a more specific type?
|
||||
|
||||
When you're super concerned about performance and memory usage.
|
||||
|
||||
That’s about it. The only reason to deviate from the defaults is to squeeze out every last bit of performance when you are writing an application that is resource-constrained. (Or, in the special case of `uint64`, you need an absurd range of unsigned integers).
|
||||
|
||||
You can [read more on this subject here](https://blog.boot.dev/golang/default-native-types-golang/) if you'd like, but it's not required.
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"question": "What does the size of a type indicate?",
|
||||
"answers": [
|
||||
"Bits",
|
||||
"Bytes",
|
||||
"Nibbles"
|
||||
]
|
||||
}
|
||||
28
course/2-variables/exercises/6a-which_type_to_use/readme.md
Normal file
28
course/2-variables/exercises/6a-which_type_to_use/readme.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Which Type Should I Use?
|
||||
|
||||
With so many types for what is essentially just a number, developers coming from languages that only have one kind of `Number` type (like JavaScript) may find the choices daunting.
|
||||
|
||||
## Prefer "default" types
|
||||
|
||||
A problem arises when we have a `uint16`, and the function we are trying to pass it into takes an `int`. We're forced to write code riddled with type casts like `int(myUint16)`.
|
||||
|
||||
This style of development can be slow and annoying to read. When Go developers stray from the “default” type for any given type family, the code can get messy quickly.
|
||||
|
||||
Unless you have a good reason to, stick to the following types:
|
||||
|
||||
* `bool`
|
||||
* `string`
|
||||
* `int`
|
||||
* `uint32`
|
||||
* `byte`
|
||||
* `rune`
|
||||
* `float64`
|
||||
* `complex128`
|
||||
|
||||
## When should I use a more specific type?
|
||||
|
||||
When you're super concerned about performance and memory usage.
|
||||
|
||||
That’s about it. The only reason to deviate from the defaults is to squeeze out every last bit of performance when you are writing an application that is resource-constrained. (Or, in the special case of `uint64`, you need an absurd range of unsigned integers).
|
||||
|
||||
You can [read more on this subject here](https://blog.boot.dev/golang/default-native-types-golang/) if you'd like, but it's not required.
|
||||
13
course/2-variables/exercises/7-constants/code.go
Normal file
13
course/2-variables/exercises/7-constants/code.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const premiumPlanName = "Premium Plan"
|
||||
premiumPlanName = "Basic Plan"
|
||||
|
||||
// don't edit below this line
|
||||
|
||||
fmt.Println("plan:", premiumPlanName)
|
||||
fmt.Println("plan:", basicPlanName)
|
||||
}
|
||||
13
course/2-variables/exercises/7-constants/complete.go
Normal file
13
course/2-variables/exercises/7-constants/complete.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const premiumPlanName = "Premium Plan"
|
||||
const basicPlanName = "Basic Plan"
|
||||
|
||||
// don't edit below this line
|
||||
|
||||
fmt.Println("plan:", premiumPlanName)
|
||||
fmt.Println("plan:", basicPlanName)
|
||||
}
|
||||
2
course/2-variables/exercises/7-constants/expected.txt
Normal file
2
course/2-variables/exercises/7-constants/expected.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
plan: Premium Plan
|
||||
plan: Basic Plan
|
||||
13
course/2-variables/exercises/7-constants/readme.md
Normal file
13
course/2-variables/exercises/7-constants/readme.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# Constants
|
||||
|
||||
Constants are declared like variables but use the `const` keyword. Constants can't use the `:=` short declaration syntax.
|
||||
|
||||
Constants can be character, string, boolean, or numeric values. They *can not* be more complex types like slices, maps and structs, which are types we will explain later.
|
||||
|
||||
As the name implies, the value of a constant can't be changed after it has been declared.
|
||||
|
||||
## Use two separate constants
|
||||
|
||||
Something weird is happening in this code.
|
||||
|
||||
What *should* be happening is that we create 2 separate constants: `premiumPlanName` and `basicPlanName`. Right now it looks like we're trying to overwrite one of them.
|
||||
12
course/2-variables/exercises/8-computed_constants/code.go
Normal file
12
course/2-variables/exercises/8-computed_constants/code.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const secondsInMinute = 60
|
||||
const minutesInHour = 60
|
||||
const secondsInHour = // ?
|
||||
|
||||
// don't edit below this line
|
||||
fmt.Println("number of seconds in an hour:", secondsInHour)
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const secondsInMinute = 60
|
||||
const minutesInHour = 60
|
||||
const secondsInHour = secondsInMinute * minutesInHour
|
||||
|
||||
// don't edit below this line
|
||||
fmt.Println("number of seconds in an hour:", secondsInHour)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
number of seconds in an hour: 3600
|
||||
25
course/2-variables/exercises/8-computed_constants/readme.md
Normal file
25
course/2-variables/exercises/8-computed_constants/readme.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Computed Constants
|
||||
|
||||
Constants must be known at compile time. More often than not they will be declared with a static value:
|
||||
|
||||
```go
|
||||
const myInt = 15
|
||||
```
|
||||
|
||||
However, constants *can be computed* so long as the computation can happen at *compile time*.
|
||||
|
||||
For example, this is valid:
|
||||
|
||||
```go
|
||||
const firstName = "Lane"
|
||||
const lastName = "Wagner"
|
||||
const fullName = firstName + " " + lastName
|
||||
```
|
||||
|
||||
That said, you *cannot* declare a constant that can only be computed at run-time.
|
||||
|
||||
## Assignment
|
||||
|
||||
Keeping track of time in a message-sending application is *critical*. Imagine getting an appointment reminder an hour **after** your doctor's visit.
|
||||
|
||||
Complete the code using a computed constant to print the number of seconds in an hour.
|
||||
14
course/2-variables/exercises/9-formatting_strings/code.go
Normal file
14
course/2-variables/exercises/9-formatting_strings/code.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const name = "Saul Goodman"
|
||||
const openRate = 30.5
|
||||
|
||||
// ?
|
||||
|
||||
// don't edit below this line
|
||||
|
||||
fmt.Println(msg)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
const name = "Saul Goodman"
|
||||
const openRate = 30.5
|
||||
|
||||
msg := fmt.Sprintf("Hi %s, your open rate is %.1f percent", name, openRate)
|
||||
|
||||
// don't edit below this line
|
||||
|
||||
fmt.Println(msg)
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
Hi Saul Goodman, your open rate is 30.5 percent
|
||||
57
course/2-variables/exercises/9-formatting_strings/readme.md
Normal file
57
course/2-variables/exercises/9-formatting_strings/readme.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# Formatting Strings in Go
|
||||
|
||||
Go follows the [printf tradition](https://cplusplus.com/reference/cstdio/printf/) from the C language. In my opinion, string formatting/interpolation in Go is currently *less* elegant than JavaScript and Python.
|
||||
|
||||
* [fmt.Printf](https://pkg.go.dev/fmt#Printf) - Prints a formatted string to [standard out](https://stackoverflow.com/questions/3385201/confused-about-stdin-stdout-and-stderr).
|
||||
* [fmt.Sprintf()](https://pkg.go.dev/fmt#Sprintf) - Returns the formatted string
|
||||
|
||||
## Examples
|
||||
|
||||
### %v - Interpolate the default representation
|
||||
|
||||
The `%v` variant prints the Go syntax representation of a value. You can usually use this if you're unsure what else to use. That said, it's better to use the type-specific variant if you can.
|
||||
|
||||
```go
|
||||
fmt.Printf("I am %v years old", 10)
|
||||
// I am 10 years old
|
||||
|
||||
fmt.Printf("I am %v years old", "way too many")
|
||||
// I am way too many years old
|
||||
```
|
||||
|
||||
### `%s` - Interpolate a string
|
||||
|
||||
```go
|
||||
fmt.Printf("I am %s years old", "way too many")
|
||||
// I am way too many years old
|
||||
```
|
||||
|
||||
### `%d` - Interpolate an integer in decimal form
|
||||
|
||||
```go
|
||||
fmt.Printf("I am %d years old", 10)
|
||||
// I am 10 years old
|
||||
```
|
||||
|
||||
### `%f` - Interpolate a decimal
|
||||
|
||||
```go
|
||||
fmt.Printf("I am %f years old", 10.523)
|
||||
// I am 10.523000 years old
|
||||
|
||||
// The ".2" rounds the number to 2 decimal places
|
||||
fmt.Printf("I am %.2f years old", 10.523)
|
||||
// I am 10.53 years old
|
||||
```
|
||||
|
||||
If you're interested in all the formatting options, feel free to take a look at the `fmt` package's [docs here](https://pkg.go.dev/fmt#hdr-Printing).
|
||||
|
||||
## Assignment
|
||||
|
||||
Create a new variable called `msg` on line 9. It's a string that contains the following:
|
||||
|
||||
```
|
||||
Hi NAME, your open rate is OPENRATE percent
|
||||
```
|
||||
|
||||
Where `NAME` is the given `name`, and `OPENRATE` is the `openRate` rounded to the nearest "tenths" place.
|
||||
Reference in New Issue
Block a user