From 04ecc4737cf6bdedd95741705c14bc8b2f960453 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20D=C3=A4schle?= Date: Fri, 27 Nov 2020 21:24:35 +0100 Subject: [PATCH] docs: extend the sum type docs (#6982) --- doc/docs.md | 88 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 13 deletions(-) diff --git a/doc/docs.md b/doc/docs.md index 3b34cdc7ee..2af503fde2 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -768,8 +768,10 @@ else { println(s) // "odd" ``` -#### Is check -You can check sum types using `if` like `match`ing them. +#### Type checks and casts +You can check the current type of a sum type using `is` and its negated form `!is`. + +You can do it either in an `if`: ```v struct Abc { val string @@ -781,22 +783,82 @@ type Alphabet = Abc | Xyz x := Alphabet(Abc{'test'}) // sum type if x is Abc { - // x is automatically cast to Abc and can be used here + // x is automatically casted to Abc and can be used here println(x) } +if x !is Abc { + println('Not Abc') +} +``` +or using `match`: +```v oksyntax +match x { + Abc { + // x is automatically casted to Abc and can be used here + println(x) + } + Xyz { + // x is automatically casted to Xyz and can be used here + println(x) + } +} ``` -If you have a struct field which should be checked, there is also a way to name an alias. -```v ignore -struct MyStruct {x int} -struct MyStruct2 {y string} +This works also with struct fields: +```v +struct MyStruct { + x int +} +struct MyStruct2 { + y string +} + type MySumType = MyStruct | MyStruct2 -struct Abc { bar MySumType } -x := Abc{ bar: MyStruct{123} } -if x.bar is MyStruct as bar { - // x.bar cannot be cast automatically - // you must explicitly state "as bar" to create a variable with the MyStruct type - println(bar) + +struct Abc { + bar MySumType +} + +x := Abc{ + bar: MyStruct{123} // MyStruct will be converted to MySumType type automatically +} + +if x.bar is MyStruct { + // x.bar is automatically casted + println(x.bar) +} + +match x.bar { + MyStruct { + // x.bar is automatically casted + println(x.bar) + } + else {} +} +``` + +Mutable variables can change, and doing a cast would be unsafe. +However, sometimes it's needed to have a type cast despite of mutability. +In this case the developer has to mark the expression with a `mut` keyword +to tell the compiler that you're aware of what you're doing. + +It works like this: +```v oksyntax +mut x := MySumType(MyStruct{123}) + +if mut x is MyStruct { + // x is casted to MyStruct even it's mutable + // without the mut keyword that wouldn't work + println(x) +} + +// same with match +match mut x { + MyStruct { + // x is casted to MyStruct even it's mutable + // without the mut keyword that wouldn't work + println(x) + } } ```