| OLD | NEW |
| 1 # Strong mode generic method prototype syntax | 1 # Strong mode generic method prototype syntax |
| 2 | 2 |
| 3 This is a summary of the current (as of January 2016) comment-based generic | 3 This is a summary of the current (as of January 2016) comment-based generic |
| 4 method syntax supported by the analyzer strong mode and the Dart Dev Compiler. | 4 method syntax supported by the analyzer strong mode and the Dart Dev Compiler. |
| 5 The comment-based syntax essentially uses the proposed actual generic method | 5 The comment-based syntax essentially uses the proposed actual generic method |
| 6 syntax, but wraps it in comments. This allows developers to experiment with | 6 syntax, but wraps it in comments. This allows developers to experiment with |
| 7 generic methods while still ensuring that their code runs on all platforms while | 7 generic methods while still ensuring that their code runs on all platforms while |
| 8 generic methods are still being evaluated for inclusion into the language. | 8 generic methods are still being evaluated for inclusion into the language. |
| 9 | 9 |
| 10 ## Declaring generic method parameters | 10 ## Declaring generic method parameters |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 Dart by writing a type followed by `/*=T*/`. So for example, `dynamic /*=T*/` | 66 Dart by writing a type followed by `/*=T*/`. So for example, `dynamic /*=T*/` |
| 67 will be interpreted as `dynamic` by all non-strong mode tools, but will be | 67 will be interpreted as `dynamic` by all non-strong mode tools, but will be |
| 68 interpreted as `T` by strong mode. In places where it is valid to leave off a | 68 interpreted as `T` by strong mode. In places where it is valid to leave off a |
| 69 type, simply writing `/*=T*/` will be interpreted as `dynamic` by non-strong | 69 type, simply writing `/*=T*/` will be interpreted as `dynamic` by non-strong |
| 70 mode tools, but will be interpreted as `T` by strong mode. For example: | 70 mode tools, but will be interpreted as `T` by strong mode. For example: |
| 71 | 71 |
| 72 ```dart | 72 ```dart |
| 73 // foo is a generic method which takes a single generic method parameter S. | 73 // foo is a generic method which takes a single generic method parameter S. |
| 74 // In strong mode, the parameter x will have type S, and the return type will | 74 // In strong mode, the parameter x will have type S, and the return type will |
| 75 // be S | 75 // be S |
| 76 // In normal mode, the parameter x will have type dynamic, and the return | 76 // In normal mode, the parameter x will have type dynamic, and the return |
| 77 // type will be dynamic. | 77 // type will be dynamic. |
| 78 dynamic/*=S*/ foo/*<S>*/(dynamic/*=S*/ x) { return x; } | 78 dynamic/*=S*/ foo/*<S>*/(dynamic/*=S*/ x) { return x; } |
| 79 ``` | 79 ``` |
| 80 | 80 |
| 81 This can be written more concisely by leaving off the `dynamic`. | 81 This can be written more concisely by leaving off the `dynamic`. |
| 82 | 82 |
| 83 ```dart | 83 ```dart |
| 84 /*=S*/ foo/*<S>*/(/*=S*/ x) {return x;} | 84 /*=S*/ foo/*<S>*/(/*=S*/ x) {return x;} |
| 85 ``` | 85 ``` |
| 86 | 86 |
| 87 You can also put a type to the left of the `/*=T/`. This type will be used | 87 You can also put a type to the left of the `/*=T/`. This type will be used |
| 88 for all non-strong mode tools. For example: | 88 for all non-strong mode tools. For example: |
| 89 | 89 |
| 90 ```dart | 90 ```dart |
| 91 // This method works with `int`, `double`, or `num`. The return type will | 91 // This method works with `int`, `double`, or `num`. The return type will |
| 92 // match the type of the parameters. | 92 // match the type of the parameters. |
| 93 num/*=T*/ pickAtRandom/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) { ... } | 93 num/*=T*/ pickAtRandom/*<T extends num>*/(num/*=T*/ x, num/*=T*/ y) { ... } |
| 94 ``` | 94 ``` |
| 95 | 95 |
| 96 | 96 |
| 97 Note that the generic parameter is in scope in the return type of the function, | 97 Note that the generic parameter is in scope in the return type of the function, |
| 98 in the argument list of the function, and in the body of the function. When | 98 in the argument list of the function, and in the body of the function. When |
| 99 declaring local variables and parameters, you can also use the `/*=T*/` syntax w
ith `var`. | 99 declaring local variables and parameters, you can also use the `/*=T*/` syntax w
ith `var`. |
| 100 | 100 |
| 101 ```dart | 101 ```dart |
| 102 // foo is a generic method that takes a single generic parameter S, and a value | 102 // foo is a generic method that takes a single generic parameter S, and a value |
| 103 // x of type S | 103 // x of type S |
| 104 void foo/*<S>*/(var /*=S*/ x) { | 104 void foo/*<S>*/(var /*=S*/ x) { |
| 105 // In strong mode, y will also have type S | 105 // In strong mode, y will also have type S |
| 106 var /*=S*/ y = x; | 106 var /*=S*/ y = x; |
| 107 | 107 |
| 108 // In strong mode, z will also have type S | 108 // In strong mode, z will also have type S |
| 109 dynamic /*=S*/ z = y; | 109 dynamic /*=S*/ z = y; |
| 110 } | 110 } |
| 111 ``` | 111 ``` |
| 112 | 112 |
| 113 Anywhere that a type literal is expected, you can also use the `/*=T*/` syntax t
o | 113 Anywhere that a type literal is expected, you can also use the `/*=T*/` syntax t
o |
| 114 produce a type literal from the generic method parameter. | 114 produce a type literal from the generic method parameter. |
| 115 | 115 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 128 You can use generic method parameters to instantiate generic classes using the | 128 You can use generic method parameters to instantiate generic classes using the |
| 129 same `/*=T*/` syntax. | 129 same `/*=T*/` syntax. |
| 130 | 130 |
| 131 ```dart | 131 ```dart |
| 132 // foo is a generic method which returns a List<S> in strong mode, | 132 // foo is a generic method which returns a List<S> in strong mode, |
| 133 // but which returns List<dynamic> in normal mode. | 133 // but which returns List<dynamic> in normal mode. |
| 134 List<dynamic /*=S*/> foo/*<S>*/(/*=S*/ x) { | 134 List<dynamic /*=S*/> foo/*<S>*/(/*=S*/ x) { |
| 135 // l0 is a list literal whose reified type will be List<S> in strong mode, | 135 // l0 is a list literal whose reified type will be List<S> in strong mode, |
| 136 // and List<dynamic> in normal mode. | 136 // and List<dynamic> in normal mode. |
| 137 var l0 = <dynamic /*=S*/>[x]; | 137 var l0 = <dynamic /*=S*/>[x]; |
| 138 | 138 |
| 139 // as above, but with a regular constructor. | 139 // as above, but with a regular constructor. |
| 140 var l1 = new List<dynamic /*=S*/>(); | 140 var l1 = new List<dynamic /*=S*/>(); |
| 141 return l1; | 141 return l1; |
| 142 } | 142 } |
| 143 ``` | 143 ``` |
| 144 | 144 |
| 145 In most cases, the entire type argument list to the generic class can be | 145 In most cases, the entire type argument list to the generic class can be |
| 146 enclosed in parentheses, eliminating the need for explicitly writing `dynamic`. | 146 enclosed in parentheses, eliminating the need for explicitly writing `dynamic`. |
| 147 | 147 |
| 148 ```dart | 148 ```dart |
| 149 // This is another way of writing the same code as above | 149 // This is another way of writing the same code as above |
| 150 List/*<S>*/ foo/*<S>*/(/*=S*/ x) { | 150 List/*<S>*/ foo/*<S>*/(/*=S*/ x) { |
| 151 // The shorthand syntax is not yet supported for list and map literals | 151 // The shorthand syntax is not yet supported for list and map literals |
| 152 var l0 = <dynamic /*=S*/>[x]; | 152 var l0 = <dynamic /*=S*/>[x]; |
| 153 | 153 |
| 154 // but with regular constructors you can use it | 154 // but with regular constructors you can use it |
| 155 var l1 = new List/*<S>*/(); | 155 var l1 = new List/*<S>*/(); |
| 156 return l1; | 156 return l1; |
| 157 } | 157 } |
| 158 ``` | 158 ``` |
| 159 | 159 |
| 160 ## Instantiating generic methods | 160 ## Instantiating generic methods |
| 161 | 161 |
| 162 Generic methods can be called without passing type arguments. Strong mode will | 162 Generic methods can be called without passing type arguments. Strong mode will |
| 163 attempt to infer the type arguments automatically. If it is unable to do so, | 163 attempt to infer the type arguments automatically. If it is unable to do so, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 191 C c = new C(); | 191 C c = new C(); |
| 192 // This line will produce a type error, because strong mode will infer | 192 // This line will produce a type error, because strong mode will infer |
| 193 // `int` as the generic argument to fill in for S | 193 // `int` as the generic argument to fill in for S |
| 194 String x = c.inferableFromArgument(3); | 194 String x = c.inferableFromArgument(3); |
| 195 | 195 |
| 196 // This line will produce a type error in strong mode, because `int` is | 196 // This line will produce a type error in strong mode, because `int` is |
| 197 // explicitly passed in as the argument to use for S | 197 // explicitly passed in as the argument to use for S |
| 198 String y = c.notInferable/*<int>*/(3); | 198 String y = c.notInferable/*<int>*/(3); |
| 199 } | 199 } |
| 200 ``` | 200 ``` |
| OLD | NEW |