| 1 | = Nilable Types = |
| 2 | |
| 3 | Cobra forces specification of variables that may be allowed to contain '''nil'''. |
| 4 | This is done by typing the variable as a nilable Type which is any typeName with a '?' suffix |
| 5 | |
| 6 | e.g. |
| 7 | {{{ |
| 8 | str as String = "Mystring" # str can only have a String value |
| 9 | strN as String? # strN may have a String value OR nil |
| 10 | |
| 11 | lazyType as Type? # Type OR nil |
| 12 | }}} |
| 13 | |
| 14 | nilable Typing can be applied to anything that can be Typed ( variables, Args, parameters, returnTypes) |
| 15 | |
| 16 | {{{ |
| 17 | def sendWelcome(cust as Customer, referral as Customer?) |
| 18 | # will not accept nil for `cust` |
| 19 | # will accept nil for `referral` |
| 20 | }}} |
| 21 | |
| 22 | == Casting to and From nilable Types == |
| 23 | |
| 24 | Sometimes it is necessary to cast an existing typed variable to a nilable type [[BR]] |
| 25 | ( e.g for receiving results of a library call) or [[BR]] |
| 26 | to cast a nilable type to its non nilable type (when you've ascertained its not nil and the receiver only takes a non nilable type) |
| 27 | |
| 28 | There is a shorthand for both of these |
| 29 | |
| 30 | Casting to a nilable version of an existing type |
| 31 | <variable> to ? |
| 32 | Casting away from nilable version |
| 33 | <variable> to ! |
| 34 | e.g. |
| 35 | {{{ |
| 36 | s as String = 'a string' |
| 37 | sn = s to ? # sn is String? |
| 38 | assert sn |
| 39 | s1 = sn to ! # s1 is String - may not get nil |
| 40 | }}} |
| 41 | |
| 42 | == nil and not nil detection and coalesce == |
| 43 | |
| 44 | You can explicitly test for nil or not nil values using normal conditionals ( true is non-nil) |
| 45 | {{{ |
| 46 | s as String = 'sss' |
| 47 | assert s |
| 48 | if s |
| 49 | print 's not nil' |
| 50 | sn as String? = nil |
| 51 | assert not sn |
| 52 | if not sn |
| 53 | print 'sn is nil' |
| 54 | }}} |
| 55 | |
| 56 | Nil test and assign or non nil test and process can be done using 'nil coalescing'[[BR]] |
| 57 | |
| 58 | '''?''' coalesce if nil.[[BR]] |
| 59 | |
| 60 | '''! ''' execute if not nil. |
| 61 | {{{ |
| 62 | stuff as String? = nil |
| 63 | defaultStuff='DEFAULT' |
| 64 | |
| 65 | stuff = stuff ? defaultStuff # coalesce nil |
| 66 | # equivalent to stuff = if (not stuff, defaultStuff, stuff) |
| 67 | # or |
| 68 | # if not stuff |
| 69 | # stuff = defaultStuff |
| 70 | assert stuff == defaultStuff |
| 71 | |
| 72 | |
| 73 | def doSomething(input as String) |
| 74 | if input # detect not nil |
| 75 | print 'Received some input.' |
| 76 | |
| 77 | i as int? = input ! .parse(input) # execute non-nil |
| 78 | # equiv to |
| 79 | # i = if(input, .parse(input), input) |
| 80 | |
| 81 | # or alternatively |
| 82 | # input = input ? '0' |
| 83 | # i as int = .parse(input) |
| 84 | |
| 85 | }}} |
| 86 | |
| 87 | |
| 88 | |