From 680ac411d7103ebd06dd0abd58c6c850128db649 Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Thu, 12 Nov 2020 19:13:37 +0000 Subject: [PATCH] doc: document sum type smart cast (#6803) --- doc/docs.md | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/doc/docs.md b/doc/docs.md index 26781c5164..3e07720cd3 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -1646,9 +1646,11 @@ To cast a sum type to one of its variants you can use `sum as Type`: struct Moon {} struct Mars {} struct Venus {} + type World = Moon | Mars | Venus fn (m Mars) dust_storm() bool { return true } + fn main() { mut w := World(Moon{}) assert w is Moon @@ -1662,7 +1664,34 @@ fn main() { } ``` -### Matching sum types +`as` will panic if `w` doesn't hold a `Mars` instance. +A safer way is to use a smart cast. + +#### Smart casting + +```v oksyntax +if w is Mars { + assert typeof(w).name == 'Mars' + if w.dust_storm() { + println('bad weather!') + } +} +``` +`w` has type `Mars` inside the body of the `if` statement. This is +known as *flow-sensitive typing*. You can also specify a variable name: + +```v oksyntax +if w is Mars as mars { + assert typeof(w).name == 'World' + if mars.dust_storm() { + println('bad weather!') + } +} +``` +`w` keeps its original type. This form is necessary if `w` is a more +complex expression than just a variable name. + +#### Matching sum types You can also use `match` to determine the variant: @@ -1670,8 +1699,11 @@ You can also use `match` to determine the variant: struct Moon {} struct Mars {} struct Venus {} + type World = Moon | Mars | Venus + fn open_parachutes(n int) { println(n) } + fn land(w World) { match w { Moon {} // no atmosphere