-
Notifications
You must be signed in to change notification settings - Fork 58
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #111 from moonbitlang/Yoorkin-patch-1
add some description of punning and `..`
- Loading branch information
Showing
1 changed file
with
56 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -357,6 +357,53 @@ struct Stack { | |
} | ||
``` | ||
|
||
#### Constructing Struct with Shorthand | ||
|
||
If you already have some variable like `name` and `email`, it's redundant to repeat those name when constructing a struct: | ||
|
||
```go | ||
fn init{ | ||
let name = "john" | ||
let email = "[email protected]" | ||
let u = { id: 0, name: name, email: email } | ||
} | ||
``` | ||
|
||
You can use shorthand instead, it behaves exactly the same. | ||
|
||
```go | ||
fn init{ | ||
let name = "john" | ||
let email = "[email protected]" | ||
let u = { id: 0, name, email } | ||
} | ||
``` | ||
|
||
#### Struct Update Syntax | ||
|
||
It's useful to create a new struct based on an existing one, but with some fields updated. | ||
|
||
```rust | ||
struct User { | ||
id: Int | ||
name: String | ||
email: String | ||
} | ||
|
||
fn to_string(self : User) -> String { | ||
"{ id: " + self.id.to_string() + | ||
", name: " + self.name + | ||
", email: " + self.email + " }" | ||
} | ||
|
||
fn init { | ||
let user = { id: 0, name: "John Doe", email: "[email protected]" } | ||
let updated_user = { ..user, email: "[email protected]" } | ||
println(user) // output: { id: 0, name: John Doe, email: [email protected] } | ||
println(updated_user) // output: { id: 0, name: John Doe, email: [email protected] } | ||
} | ||
``` | ||
|
||
### Enum | ||
|
||
Enum types are similar to algebraic data types in functional languages. An enum can have a set of cases. Additionally, every case can specify associated values of different types, similar to a tuple. The label for every case must be capitalized, which is called a data constructor. An enum can be constructed by calling a data constructor with arguments of specified types. The construction of an enum must be annotated with a type. An enum can be destructed by pattern matching, and the associated values can be bound to variables that are specified in each pattern. | ||
|
@@ -386,14 +433,22 @@ fn init { | |
|
||
## Pattern Matching | ||
|
||
We have shown a use case of pattern matching for enums, but pattern matching is not restricted to enums. For example, we can also match expressions against Boolean values, numbers, characters, strings, tuples, arrays, and struct literals. Since there is only one case for those types other than enums, we can pattern match them using `let`/`var` binding instead of `match` expressions. Note that the scope of bound variables in `match` is limited to the case where the variable is introduced, while `let`/`var` binding will introduce every variable to the current scope. Furthermore, we can use underscores `_` as wildcards for the values we don’t care about. | ||
We have shown a use case of pattern matching for enums, but pattern matching is not restricted to enums. For example, we can also match expressions against Boolean values, numbers, characters, strings, tuples, arrays, and struct literals. Since there is only one case for those types other than enums, we can pattern match them using `let`/`var` binding instead of `match` expressions. Note that the scope of bound variables in `match` is limited to the case where the variable is introduced, while `let`/`var` binding will introduce every variable to the current scope. Furthermore, we can use underscores `_` as wildcards for the values we don’t care about, use `..` to ignore remaining fields of struct or elements of array. | ||
|
||
```go | ||
let id = match u { | ||
{ id: id, name: _, email: _ } => id | ||
} | ||
// is equivalent to | ||
let { id: id, name: _, email: _ } = u | ||
// or | ||
let { id: id, ..} = u | ||
``` | ||
|
||
```go | ||
let ary = [1,2,3,4] | ||
let [a, b, ..] = ary // a = 1, b = 2 | ||
let [.., a, b] = ary // a = 3, b = 4 | ||
``` | ||
|
||
There are some other useful constructs in pattern matching. For example, we can use `as` to give a name to some pattern, and we can use `|` to match several cases at once. A variable name can only be bound once in a single pattern, and the same set of variables should be bound on both sides of `|` patterns. | ||
|