Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2 | |
Robert Griesemer | c59d2f1 | 2008-09-09 10:48:14 -0700 | [diff] [blame] | 3 | <!-- |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 4 | Biggest open issues: |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 5 | [ ] General iterators |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 6 | [ ] Conversions: |
| 7 | - current situation is messy |
| 8 | - 2 (3?) different notations for the same thing |
| 9 | - unclear when a type guard is needed |
| 10 | - unclear where conversions can be applied |
| 11 | - for type T int; can we say T(3.0) ? |
| 12 | - do we need channel conversion (channel direction) |
| 13 | [ ] Semantics of type declaration: |
| 14 | - creating a new type (status quo), or only a new type name? |
| 15 | - also: declaration type T S; strips methods of S. why/why not? |
| 16 | |
| 17 | |
Robert Griesemer | 1593ab6 | 2009-01-16 15:36:46 -0800 | [diff] [blame] | 18 | Decisions in need of integration into the doc: |
| 19 | [ ] pair assignment is required to get map, and receive ok. |
| 20 | [ ] len() returns an int, new(array_type, n) n must be an int |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 21 | |
| 22 | |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 23 | Todo's: |
Robert Griesemer | d8a764c | 2009-02-06 17:01:10 -0800 | [diff] [blame] | 24 | [ ] there is some funny-ness regarding ';' and empty statements and label decls |
Robert Griesemer | 9f4a27c | 2009-01-16 15:44:08 -0800 | [diff] [blame] | 25 | [ ] document illegality of package-external tuple assignments to structs |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 26 | w/ private fields: P.T(1, 2) illegal since same as P.T(a: 1, b: 2) for |
Robert Griesemer | 9f4a27c | 2009-01-16 15:44:08 -0800 | [diff] [blame] | 27 | a T struct { a b int }. |
Robert Griesemer | c59d2f1 | 2008-09-09 10:48:14 -0700 | [diff] [blame] | 28 | [ ] clarification on interface types, rules |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 29 | [ ] clarify tuples |
| 30 | [ ] need to talk about precise int/floats clearly |
| 31 | [ ] iant suggests to use abstract/precise int for len(), cap() - good idea |
| 32 | (issue: what happens in len() + const - what is the type?) |
Robert Griesemer | 1593ab6 | 2009-01-16 15:36:46 -0800 | [diff] [blame] | 33 | [ ] cleanup convert() vs T() vs x.(T) - convert() should go away? |
Robert Griesemer | 1593ab6 | 2009-01-16 15:36:46 -0800 | [diff] [blame] | 34 | [ ] fix "else" part of if statement |
| 35 | [ ] cleanup: 6g allows: interface { f F } where F is a function type. |
| 36 | fine, but then we should also allow: func f F {}, where F is a function type. |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 37 | |
| 38 | |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 39 | Wish list: |
| 40 | [ ] enum facility (enum symbols that are not mixable with ints) or some other |
| 41 | mechanism to obtain type-safety which we don't have with int-only tags |
| 42 | [ ] Gri: built-in assert() - alternatively: allow entire expressions |
| 43 | as statements so we can write: some_condition || panic(); (along these lines) |
| 44 | [ ] Helper syntax for composite types: allow names/keys/indices for |
| 45 | structs/maps/arrays, remove need for type in elements of composites |
| 46 | |
| 47 | |
| 48 | Smaller issues: |
Robert Griesemer | 1593ab6 | 2009-01-16 15:36:46 -0800 | [diff] [blame] | 49 | [ ] need for type switch? (or use type guard with ok in tuple assignment?) |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 50 | [ ] Is . import implemented / do we still need it? |
Robert Griesemer | 7271e04 | 2008-10-09 20:05:24 -0700 | [diff] [blame] | 51 | [ ] Do we allow empty statements? If so, do we allow empty statements after a label? |
| 52 | and if so, does a label followed by an empty statement (a semicolon) still denote |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 53 | a for loop that is following, and can break L be used inside it? |
Robert Griesemer | ac05579 | 2008-09-26 11:15:14 -0700 | [diff] [blame] | 54 | |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 55 | |
| 56 | Closed: |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 57 | [x] Russ: If we use x.(T) for all conversions, we could use T() for "construction" |
| 58 | and type literals - would resolve the parsing ambiguity of T{} in if's - |
| 59 | switching to () for literals, conversion discussion still open |
Robert Griesemer | d8a764c | 2009-02-06 17:01:10 -0800 | [diff] [blame] | 60 | [x] Russ: consider re-introducing "func" for function type. Make function literals |
| 61 | behave like slices, etc. Require no &'s to get a function value (solves issue |
| 62 | of func{} vs &func{} vs &func_name). |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 63 | [x] onreturn/undo statement - now: defer statement |
| 64 | [x] comparison of non-basic types: what do we allow? what do we allow in interfaces |
| 65 | what about maps (require ==, copy and hash) |
| 66 | maybe: no maps with non-basic type keys, and no interface comparison unless |
| 67 | with nil[x] |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 68 | [x] clarify slice rules |
| 69 | [x] what are the permissible ranges for the indices in slices? The spec |
| 70 | doesn't correspond to the implementation. The spec is wrong when it |
| 71 | comes to the first index i: it should allow (at least) the range 0 <= i <= len(a). |
| 72 | also: document different semantics for strings and arrays (strings cannot be grown). |
Robert Griesemer | 1593ab6 | 2009-01-16 15:36:46 -0800 | [diff] [blame] | 73 | [x] reopening & and func issue: Seems inconsistent as both &func(){} and func(){} are |
| 74 | permitted. Suggestion: func literals are pointers. We need to use & for all other |
| 75 | functions. This would be in consistency with the declaration of function pointer |
| 76 | variables and the use of '&' to convert methods into function pointers. |
| 77 | - covered by other entry |
| 78 | [x] composite types should uniformly create an instance instead of a pointer - fixed |
| 79 | [x] like to have assert() in the language, w/ option to disable code gen for it |
| 80 | - added to wish list |
| 81 | [x] convert should not be used for composite literals anymore, |
| 82 | in fact, convert() should go away - made a todo |
| 83 | [x] type switch or some form of type test needed - duplicate entry |
| 84 | [x] provide composite literal notation to address array indices: []int{ 0: x1, 1: x2, ... } |
| 85 | and struct field names (both seem easy to do). - under "Missing" list |
| 86 | [x] passing a "..." arg to another "..." parameter doesn't wrap the argument again |
| 87 | (so "..." args can be passed down easily) - this is documented |
| 88 | [x] consider syntactic notation for composite literals to make them parseable w/o type information |
| 89 | (require ()'s in control clauses) - use heuristics for now |
| 90 | [x] do we need anything on package vs file names? - current package scheme workable for now |
| 91 | [x] what is the meaning of typeof() - we don't have it |
| 92 | [x] old-style export decls (still needed, but ideally should go away) |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 93 | [x] packages of multiple files - we have a working approach |
| 94 | [x] partial export of structs, methods |
Robert Griesemer | 91bbd64 | 2009-01-07 09:31:35 -0800 | [diff] [blame] | 95 | [x] new as it is now is weird - need to go back to previous semantics and introduce |
| 96 | literals for slices, maps, channels - done |
| 97 | [x] determine if really necessary to disallow array assignment - allow array assignment |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 98 | [x] semantics of statements - we just need to fill in the language, the semantics is mostly clear |
| 99 | [x] range statement: to be defined more reasonably |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 100 | [x] need to be specific on (unsigned) integer operations: one must be able |
| 101 | to rely on wrap-around on overflow |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 102 | [x] global var decls: "var a, b, c int = 0, 0, 0" is ok, but "var a, b, c = 0, 0, 0" is not |
| 103 | (seems inconsistent with "var a = 0", and ":=" notation) |
| 104 | [x] const decls: "const a, b = 1, 2" is not allowed - why not? Should be symmetric to vars. |
Robert Griesemer | f618f89 | 2008-11-03 10:52:28 -0800 | [diff] [blame] | 105 | [x] new(arraytype, n1, n2): spec only talks about length, not capacity |
| 106 | (should only use new(arraytype, n) - this will allow later |
| 107 | extension to multi-dim arrays w/o breaking the language) - documented |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 108 | [x] should we have a shorter list of alias types? (byte, int, uint, float) - done |
| 109 | [x] reflection support |
| 110 | [x] syntax for var args |
Robert Griesemer | 4712165 | 2008-10-23 17:19:56 -0700 | [diff] [blame] | 111 | [x] Do composite literals create a new literal each time (gri thinks yes) (Russ is putting in a change |
| 112 | to this effect, essentially) |
Robert Griesemer | b5e0cc7 | 2008-10-10 16:34:44 -0700 | [diff] [blame] | 113 | [x] comparison operators: can we compare interfaces? |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 114 | [x] can we add methods to types defined in another package? (probably not) |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 115 | [x] optional semicolons: too complicated and unclear |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 116 | [x] anonymous types are written using a type name, which can be a qualified identifier. |
| 117 | this might be a problem when referring to such a field using the type name. |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 118 | [x] nil and interfaces - can we test for nil, what does it mean, etc. |
| 119 | [x] talk about underflow/overflow of 2's complement numbers (defined vs not defined). |
Robert Griesemer | c59b2a3 | 2008-09-30 10:57:59 -0700 | [diff] [blame] | 120 | [x] change wording on array composite literals: the types are always fixed arrays |
| 121 | for array composites |
Robert Griesemer | a1065fa | 2008-09-29 20:37:46 -0700 | [diff] [blame] | 122 | [x] meaning of nil |
Robert Griesemer | ac05579 | 2008-09-26 11:15:14 -0700 | [diff] [blame] | 123 | [x] remove "any" |
| 124 | [x] methods for all types |
| 125 | [x] should binary <- be at lowest precedence level? when is a send/receive non-blocking? (NO - 9/19/08) |
| 126 | [x] func literal like a composite type - should probably require the '&' to get address (NO) |
| 127 | [x] & needed to get a function pointer from a function? (NO - there is the "func" keyword - 9/19/08) |
Robert Griesemer | 1593ab6 | 2009-01-16 15:36:46 -0800 | [diff] [blame] | 128 | |
| 129 | Timeline (9/5/08): |
| 130 | - threads: 1 month |
| 131 | - reflection code: 2 months |
| 132 | - proto buf support: 3 months |
| 133 | - GC: 6 months |
| 134 | - debugger |
| 135 | - Jan 1, 2009: enough support to write interesting programs |
Robert Griesemer | c59d2f1 | 2008-09-09 10:48:14 -0700 | [diff] [blame] | 136 | --> |
| 137 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 138 | <h2>Introduction</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 139 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 140 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 141 | This is a reference manual for the Go programming language. For |
| 142 | more information and other documents, see <a |
| 143 | href="/">the Go home page</a>. |
| 144 | </p> |
Robert Griesemer | 6715358 | 2008-12-16 14:45:09 -0800 | [diff] [blame] | 145 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 146 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 147 | Go is a general-purpose language designed with systems programming |
| 148 | in mind. It is strongly typed and garbage-collected, and has explicit |
| 149 | support for concurrent programming. Programs are constructed from |
| 150 | <i>packages</i>, whose properties allow efficient management of |
| 151 | dependencies. The existing implementations use a traditional |
| 152 | compile/link model to generate executable binaries. |
| 153 | </p> |
| 154 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 155 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 156 | The grammar is compact and regular, allowing for easy analysis by |
| 157 | automatic tools such as integrated development environments. |
| 158 | </p> |
Rob Pike | fd1f383 | 2009-02-19 19:49:56 -0800 | [diff] [blame^] | 159 | <hr> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 160 | <h2>Notation</h2> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 161 | <p> |
Robert Griesemer | 4d23030 | 2008-12-17 15:39:15 -0800 | [diff] [blame] | 162 | The syntax is specified using Extended Backus-Naur Form (EBNF): |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 163 | </p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 164 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 165 | <pre> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 166 | Production = production_name "=" Expression . |
| 167 | Expression = Alternative { "|" Alternative } . |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 168 | Alternative = Term { Term } . |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 169 | Term = production_name | token [ "..." token ] | Group | Option | Repetition . |
| 170 | Group = "(" Expression ")" . |
| 171 | Option = "[" Expression ")" . |
| 172 | Repetition = "{" Expression "}" . |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 173 | </pre> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 174 | |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 175 | <p> |
| 176 | Productions are expressions constructed from terms and the following |
| 177 | operators, in increasing precedence: |
| 178 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 179 | <pre> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 180 | | alternation |
| 181 | () grouping |
| 182 | [] option (0 or 1 times) |
| 183 | {} repetition (0 to n times) |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 184 | </pre> |
Robert Griesemer | 4d23030 | 2008-12-17 15:39:15 -0800 | [diff] [blame] | 185 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 186 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 187 | Lower-case production names are used to identify lexical tokens. |
| 188 | Non-terminals are in CamelCase. Lexical symbols are enclosed in |
| 189 | double quotes <tt>""</tt> (the double quote symbol is written as |
| 190 | <tt>'"'</tt>). |
| 191 | </p> |
| 192 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 193 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 194 | The form <tt>"a ... b"</tt> represents the set of characters from |
| 195 | <tt>a</tt> through <tt>b</tt> as alternatives. |
| 196 | </p> |
| 197 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 198 | <p> |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 199 | Where possible, recursive productions are used to express evaluation order |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 200 | and operator precedence syntactically. |
| 201 | </p> |
Rob Pike | fd1f383 | 2009-02-19 19:49:56 -0800 | [diff] [blame^] | 202 | <hr> |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 203 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 204 | <h2>Source code representation</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 205 | |
| 206 | Source code is Unicode text encoded in UTF-8. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 207 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 208 | Tokenization follows the usual rules. Source text is case-sensitive. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 209 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 210 | White space is blanks, newlines, carriage returns, or tabs. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 211 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 212 | Comments are // to end of line or /* */ without nesting and are treated as white space. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 213 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 214 | Some Unicode characters (e.g., the character U+00E4) may be representable in |
| 215 | two forms, as a single code point or as two code points. For simplicity of |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 216 | implementation, Go treats these as distinct characters: each Unicode code |
| 217 | point is a single character in Go. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 218 | |
| 219 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 220 | <h3>Characters</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 221 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 222 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 223 | The following terms are used to denote specific Unicode character classes: |
| 224 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 225 | <ul> |
| 226 | <li>unicode_char an arbitrary Unicode code point |
| 227 | <li>unicode_letter a Unicode code point classified as "Letter" |
| 228 | <li>capital_letter a Unicode code point classified as "Letter, uppercase" |
| 229 | </ul> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 230 | |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 231 | (The Unicode Standard, Section 4.5 General Category - Normative.) |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 232 | |
| 233 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 234 | <h3>Letters and digits</h3> |
| 235 | <pre> |
| 236 | letter = unicode_letter | "_" . |
| 237 | decimal_digit = "0" ... "9" . |
| 238 | octal_digit = "0" ... "7" . |
| 239 | hex_digit = "0" ... "9" | "A" ... "F" | "a" ... "f" . |
| 240 | </pre> |
| 241 | <hr> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 242 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 243 | <h2>Vocabulary</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 244 | |
| 245 | Tokens make up the vocabulary of the Go language. They consist of |
| 246 | identifiers, numbers, strings, operators, and delimitors. |
| 247 | |
| 248 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 249 | <h3>Identifiers</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 250 | |
| 251 | An identifier is a name for a program entity such as a variable, a |
| 252 | type, a function, etc. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 253 | <pre> |
| 254 | identifier = letter { letter | decimal_digit } . |
| 255 | </pre> |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 256 | Exported identifiers (§Exported identifiers) start with a capital_letter. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 257 | <pre> |
| 258 | a |
| 259 | _x9 |
| 260 | ThisVariableIsExported |
| 261 | αβ |
| 262 | </pre> |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 263 | Some identifiers are predeclared (§Predeclared identifiers). |
Robert Griesemer | 7a4ed4f | 2008-09-03 15:15:51 -0700 | [diff] [blame] | 264 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 265 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 266 | <h3>Numeric literals</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 267 | |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 268 | An integer literal represents a mathematically ideal integer constant |
| 269 | of arbitrary precision, or 'ideal int'. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 270 | <pre> |
| 271 | int_lit = decimal_int | octal_int | hex_int . |
| 272 | decimal_int = ( "1" ... "9" ) { decimal_digit } . |
| 273 | octal_int = "0" { octal_digit } . |
| 274 | hex_int = "0" ( "x" | "X" ) hex_digit { hex_digit } . |
| 275 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 276 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 277 | <pre> |
| 278 | 42 |
| 279 | 0600 |
| 280 | 0xBadFace |
| 281 | 170141183460469231731687303715884105727 |
| 282 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 283 | |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 284 | A floating point literal represents a mathematically ideal floating point |
| 285 | constant of arbitrary precision, or 'ideal float'. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 286 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 287 | <pre> |
| 288 | float_lit = |
| 289 | decimals "." [ decimals ] [ exponent ] | |
| 290 | decimals exponent | |
| 291 | "." decimals [ exponent ] . |
| 292 | decimals = decimal_digit { decimal_digit } . |
| 293 | exponent = ( "e" | "E" ) [ "+" | "-" ] decimals . |
| 294 | </pre> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 295 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 296 | <pre> |
| 297 | 0. |
| 298 | 2.71828 |
| 299 | 1.e+0 |
| 300 | 6.67428e-11 |
| 301 | 1E6 |
| 302 | .25 |
| 303 | .12345E+5 |
| 304 | </pre> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 305 | |
| 306 | Numeric literals are unsigned. A negative constant is formed by |
| 307 | applying the unary prefix operator "-" (§Arithmetic operators). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 308 | <p> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 309 | An 'ideal number' is either an 'ideal int' or an 'ideal float'. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 310 | <p> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 311 | Only when an ideal number (or an arithmetic expression formed |
| 312 | solely from ideal numbers) is bound to a variable or used in an expression |
| 313 | or constant of fixed-size integers or floats it is required to fit |
| 314 | a particular size. In other words, ideal numbers and arithmetic |
| 315 | upon them are not subject to overflow; only use of them in assignments |
| 316 | or expressions involving fixed-size numbers may cause overflow, and thus |
| 317 | an error (§Expressions). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 318 | <p> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 319 | Implementation restriction: A compiler may implement ideal numbers |
| 320 | by choosing a "sufficiently large" internal representation of such |
| 321 | numbers. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 322 | |
| 323 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 324 | <h3>Character and string literals</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 325 | |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 326 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 327 | Character and string literals are almost the same as in C, with the |
| 328 | following differences: |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 329 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 330 | <ul> |
| 331 | <li>The encoding is UTF-8 |
| 332 | <li>`` strings exist; they do not interpret backslashes |
| 333 | <li>Octal character escapes are always 3 digits ("\077" not "\77") |
| 334 | <li>Hexadecimal character escapes are always 2 digits ("\x07" not "\x7") |
| 335 | </ul> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 336 | |
Robert Griesemer | cae0342 | 2008-09-04 16:59:31 -0700 | [diff] [blame] | 337 | The rules are: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 338 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 339 | <pre> |
| 340 | escaped_char = "\" ( "a" | "b" | "f" | "n" | "r" | "t" | "v" | "\" | "'" | """ ) . |
| 341 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 342 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 343 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 344 | A unicode_value takes one of four forms: |
| 345 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 346 | <ul> |
| 347 | <li>The UTF-8 encoding of a Unicode code point. Since Go source |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 348 | text is in UTF-8, this is the obvious translation from input |
| 349 | text into Unicode characters. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 350 | |
| 351 | <li>The usual list of C backslash escapes: "\n", "\t", etc. |
Robert Griesemer | cae0342 | 2008-09-04 16:59:31 -0700 | [diff] [blame] | 352 | Within a character or string literal, only the corresponding quote character |
| 353 | is a legal escape (this is not explicitly reflected in the above syntax). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 354 | |
| 355 | <li>A `little u' value, such as "\u12AB". This represents the Unicode |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 356 | code point with the corresponding hexadecimal value. It always |
| 357 | has exactly 4 hexadecimal digits. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 358 | |
| 359 | <li>A `big U' value, such as "\U00101234". This represents the |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 360 | Unicode code point with the corresponding hexadecimal value. |
| 361 | It always has exactly 8 hexadecimal digits. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 362 | </ul> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 363 | |
| 364 | Some values that can be represented this way are illegal because they |
| 365 | are not valid Unicode code points. These include values above |
| 366 | 0x10FFFF and surrogate halves. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 367 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 368 | An octal_byte_value contains three octal digits. A hex_byte_value |
| 369 | contains two hexadecimal digits. (Note: This differs from C but is |
| 370 | simpler.) |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 371 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 372 | It is erroneous for an octal_byte_value to represent a value larger than 255. |
| 373 | (By construction, a hex_byte_value cannot.) |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 374 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 375 | A character literal is a form of unsigned integer constant. Its value |
| 376 | is that of the Unicode code point represented by the text between the |
| 377 | quotes. |
| 378 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 379 | <pre> |
| 380 | 'a' |
| 381 | 'ä' |
| 382 | '本' |
| 383 | '\t' |
| 384 | '\000' |
| 385 | '\007' |
| 386 | '\377' |
| 387 | '\x07' |
| 388 | '\xff' |
| 389 | '\u12e4' |
| 390 | '\U00101234' |
| 391 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 392 | |
| 393 | String literals come in two forms: double-quoted and back-quoted. |
| 394 | Double-quoted strings have the usual properties; back-quoted strings |
| 395 | do not interpret backslashes at all. |
| 396 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 397 | <pre> |
| 398 | string_lit = raw_string_lit | interpreted_string_lit . |
| 399 | raw_string_lit = "`" { unicode_char } "`" . |
| 400 | interpreted_string_lit = """ { unicode_value | byte_value } """ . |
| 401 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 402 | |
Robert Griesemer | cd49927 | 2008-09-29 12:09:00 -0700 | [diff] [blame] | 403 | A string literal has type "string" (§Strings). Its value is constructed |
| 404 | by taking the byte values formed by the successive elements of the |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 405 | literal. For byte_values, these are the literal bytes; for |
| 406 | unicode_values, these are the bytes of the UTF-8 encoding of the |
| 407 | corresponding Unicode code points. Note that |
| 408 | "\u00FF" |
| 409 | and |
| 410 | "\xFF" |
| 411 | are |
| 412 | different strings: the first contains the two-byte UTF-8 expansion of |
| 413 | the value 255, while the second contains a single byte of value 255. |
| 414 | The same rules apply to raw string literals, except the contents are |
| 415 | uninterpreted UTF-8. |
| 416 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 417 | <pre> |
| 418 | `abc` |
| 419 | `\n` |
| 420 | "hello, world\n" |
| 421 | "\n" |
| 422 | "" |
| 423 | "Hello, world!\n" |
| 424 | "日本語" |
| 425 | "\u65e5本\U00008a9e" |
| 426 | "\xff\u00FF" |
| 427 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 428 | |
| 429 | These examples all represent the same string: |
| 430 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 431 | <pre> |
| 432 | "日本語" // UTF-8 input text |
| 433 | `日本語` // UTF-8 input text as a raw literal |
| 434 | "\u65e5\u672c\u8a9e" // The explicit Unicode code points |
| 435 | "\U000065e5\U0000672c\U00008a9e" // The explicit Unicode code points |
| 436 | "\xe6\x97\xa5\xe6\x9c\xac\xe8\xaa\x9e" // The explicit UTF-8 bytes |
| 437 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 438 | |
Robert Griesemer | cd49927 | 2008-09-29 12:09:00 -0700 | [diff] [blame] | 439 | Adjacent strings separated only by whitespace (including comments) |
| 440 | are concatenated into a single string. The following two lines |
| 441 | represent the same string: |
| 442 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 443 | <pre> |
| 444 | "Alea iacta est." |
| 445 | "Alea " /* The die */ `iacta est` /* is cast */ "." |
| 446 | </pre> |
Robert Griesemer | cd49927 | 2008-09-29 12:09:00 -0700 | [diff] [blame] | 447 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 448 | The language does not canonicalize Unicode text or evaluate combining |
| 449 | forms. The text of source code is passed uninterpreted. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 450 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 451 | If the source code represents a character as two code points, such as |
| 452 | a combining form involving an accent and a letter, the result will be |
| 453 | an error if placed in a character literal (it is not a single code |
| 454 | point), and will appear as two code points if placed in a string |
| 455 | literal. |
| 456 | |
| 457 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 458 | <h3>Operators and delimitors</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 459 | |
| 460 | The following special character sequences serve as operators or delimitors: |
| 461 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 462 | <pre> |
| 463 | + & += &= && == != ( ) |
| 464 | - | -= |= || < <= [ ] |
| 465 | * ^ *= ^= <- > >= { } |
| 466 | / << /= <<= ++ = := , ; |
| 467 | % >> %= >>= -- ! ... . : |
| 468 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 469 | |
| 470 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 471 | <h3>Reserved words</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 472 | |
| 473 | The following words are reserved and must not be used as identifiers: |
| 474 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 475 | <pre> |
| 476 | break default func interface select |
| 477 | case defer go map struct |
| 478 | chan else goto package switch |
| 479 | const fallthrough if range type |
| 480 | continue for import return var |
| 481 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 482 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 483 | <hr> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 484 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 485 | <h2>Declarations and scope rules</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 486 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 487 | A declaration ``binds'' an identifier to a language entity (such as |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 488 | a package, constant, type, struct field, variable, parameter, result, |
| 489 | function, method) and specifies properties of that entity such as its type. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 490 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 491 | <pre> |
| 492 | Declaration = ConstDecl | TypeDecl | VarDecl | FunctionDecl | MethodDecl . |
| 493 | </pre> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 494 | |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 495 | Every identifier in a program must be declared; some identifiers, such as "int" |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 496 | and "true", are predeclared (§Predeclared identifiers). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 497 | <p> |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 498 | The ``scope'' of an identifier is the extent of source text within which the |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 499 | identifier denotes the bound entity. No identifier may be declared twice in a |
| 500 | single scope. Go is lexically scoped: An identifier denotes the entity it is |
| 501 | bound to only within the scope of the identifier. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 502 | <p> |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 503 | For instance, for a variable named "x", the scope of identifier "x" is the |
| 504 | extent of source text within which "x" denotes that particular variable. |
| 505 | It is illegal to declare another identifier "x" within the same scope. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 506 | <p> |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 507 | The scope of an identifier depends on the entity declared. The scope for |
| 508 | an identifier always excludes scopes redeclaring the identifier in nested |
| 509 | blocks. An identifier declared in a nested block is said to ``shadow'' the |
| 510 | same identifier declared in an outer block. |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 511 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 512 | <ol> |
| 513 | <li> The scope of predeclared identifiers is the entire source file. |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 514 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 515 | <li> The scope of an identifier denoting a type, function or package |
| 516 | extends textually from the point of the identifier in the declaration |
| 517 | to the end of the innermost surrounding block. |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 518 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 519 | <li> The scope of a constant or variable extends textually from |
| 520 | after the declaration to the end of the innermost surrounding |
| 521 | block. If the variable is declared in the init statement of an |
| 522 | if, for, or switch statement, the innermost surrounding block |
| 523 | is the block associated with the respective statement. |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 524 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 525 | <li> The scope of a parameter or result identifier is the body of the |
| 526 | corresponding function. |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 527 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 528 | <li> The scope of a field or method identifier is selectors for the |
| 529 | corresponding type containing the field or method (§Selectors). |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 530 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 531 | <li> The scope of a label is the body of the innermost surrounding |
| 532 | function and does not intersect with any non-label scope. Thus, |
| 533 | each function has its own private label scope. |
| 534 | </ol> |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 535 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 536 | <h3>Predeclared identifiers</h3> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 537 | |
| 538 | The following identifiers are predeclared: |
| 539 | |
| 540 | All basic types: |
| 541 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 542 | <pre> |
| 543 | bool, byte, uint8, uint16, uint32, uint64, int8, int16, int32, int64, |
| 544 | float32, float64, string |
| 545 | </pre> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 546 | |
| 547 | A set of platform-specific convenience types: |
| 548 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 549 | <pre> |
| 550 | uint, int, float, uintptr |
| 551 | </pre> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 552 | |
| 553 | The predeclared constants: |
| 554 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 555 | <pre> |
| 556 | true, false, iota, nil |
| 557 | </pre> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 558 | |
| 559 | The predeclared functions (note: this list is likely to change): |
| 560 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 561 | <pre> |
| 562 | cap(), convert(), len(), make(), new(), panic(), panicln(), print(), println(), typeof(), ... |
| 563 | </pre> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 564 | |
| 565 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 566 | <h3>Exported identifiers</h3> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 567 | |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 568 | Identifiers that start with a capital_letter (§Identifiers) are ``exported'', |
| 569 | thus making the identifiers accessible outside the current package. A file |
| 570 | belonging to another package may then import the package (§Packages) and access |
| 571 | exported identifiers via qualified identifiers (§Qualified identifiers). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 572 | <p> |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 573 | All other identifiers are ``internal''; they are only visible in files |
| 574 | belonging to the same package which declares them. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 575 | <p> |
| 576 | <font color=red> |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 577 | TODO: This should be made clearer. For instance, function-local identifiers |
| 578 | are never exported, but non-global fields/methods may be exported. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 579 | </font> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 580 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 581 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 582 | <h3>Const declarations</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 583 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 584 | A constant declaration binds an identifier to the value of a constant |
| 585 | expression (§Constant expressions). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 586 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 587 | <pre> |
| 588 | ConstDecl = "const" ( ConstSpec | "(" [ ConstSpecList ] ")" ) . |
| 589 | ConstSpecList = ConstSpec { ";" ConstSpec } [ ";" ] . |
| 590 | ConstSpec = IdentifierList [ CompleteType ] [ "=" ExpressionList ] . |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 591 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 592 | IdentifierList = identifier { "," identifier } . |
| 593 | ExpressionList = Expression { "," Expression } . |
| 594 | </pre> |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 595 | |
| 596 | A constant declaration binds a list of identifiers (the names of the constants) |
| 597 | to the values of a list of constant expressions. The number of identifiers must |
| 598 | be equal to the number of expressions, with the i'th identifier on the left |
| 599 | corresponding to the i'th expression on the right. If CompleteType is omitted, |
| 600 | the types of the constants are the types of the corresponding expressions; |
| 601 | different expressions may have different types. If CompleteType is present, |
| 602 | the type of all constants is the type specified, and the types of all |
| 603 | expressions in ExpressionList must be assignment-compatible with the |
| 604 | constant type. |
| 605 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 606 | <pre> |
| 607 | const Pi float64 = 3.14159265358979323846 |
| 608 | const E = 2.718281828 |
| 609 | const ( |
| 610 | size int64 = 1024; |
| 611 | eof = -1; |
| 612 | ) |
| 613 | const a, b, c = 3, 4, "foo" // a = 3, b = 4, c = "foo" |
| 614 | const u, v float = 0, 3 // u = 0.0, v = 3.0 |
| 615 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 616 | |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 617 | As a special case, within a parenthesized "const" declaration list the |
| 618 | ExpressionList may be omitted from any but the first declaration. Such an empty |
| 619 | ExpressionList is equivalent to the textual substitution of the first preceding |
| 620 | non-empty ExpressionList in the same "const" declaration list. |
| 621 | That is, omitting the list of expressions is equivalent to repeating the |
| 622 | previous list. The number of identifiers must be equal to the number of |
| 623 | expressions in the previous list. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 624 | <p> |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 625 | Together with the "iota" constant generator implicit repetition of |
| 626 | ExpressionLists permit light-weight declaration of enumerated values (§Iota): |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 627 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 628 | <pre> |
| 629 | const ( |
| 630 | Sunday = iota; |
| 631 | Monday; |
| 632 | Tuesday; |
| 633 | Wednesday; |
| 634 | Thursday; |
| 635 | Friday; |
| 636 | Partyday; |
| 637 | numberOfDays; // this constant in not exported |
| 638 | ) |
| 639 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 640 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 641 | The initializing expression for a numeric constant is evaluated |
| 642 | using the principles described in the section on numeric literals: |
| 643 | constants are mathematical values given a size only upon assignment |
| 644 | to a variable. Intermediate values, and the constants themselves, |
| 645 | may require precision significantly larger than any concrete type |
| 646 | in the language. Thus the following is legal: |
| 647 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 648 | <pre> |
| 649 | const Huge = 1 << 100; |
| 650 | const Four int8 = Huge >> 98; |
| 651 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 652 | |
| 653 | A given numeric constant expression is, however, defined to be |
| 654 | either an integer or a floating point value, depending on the syntax |
| 655 | of the literals it comprises (123 vs. 1.0e4). This is because the |
| 656 | nature of the arithmetic operations depends on the type of the |
| 657 | values; for example, 3/2 is an integer division yielding 1, while |
| 658 | 3./2. is a floating point division yielding 1.5. Thus |
| 659 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 660 | <pre> |
| 661 | const x = 3./2. + 3/2; |
| 662 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 663 | |
| 664 | yields a floating point constant of value 2.5 (1.5 + 1); its |
| 665 | constituent expressions are evaluated using different rules for |
| 666 | division. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 667 | <p> |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 668 | If the type is missing from a numeric constant declaration, the constant |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 669 | represents a value of abitrary precision, either integer or floating |
| 670 | point, determined by the type of the initializing expression. Such |
| 671 | a constant may be assigned to any variable that can represent its |
| 672 | value accurately, regardless of type. For instance, 3 can be |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 673 | assigned to any integer variable but also to any floating point variable, |
| 674 | while 1e12 can be assigned to a "float32", "float64", or even "int64". |
| 675 | It is erroneous to assign a value with a non-zero fractional part |
| 676 | to an integer, or if the assignment would overflow or underflow. |
| 677 | |
| 678 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 679 | <h3>Iota</h3> |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 680 | |
| 681 | Within a constant declaration, the predeclared operand "iota" represents |
| 682 | successive elements of an integer sequence. It is reset to 0 whenever the |
| 683 | reserved word "const" appears in the source and increments with each |
| 684 | semicolon. For instance, "iota" can be used to construct a set of related |
| 685 | constants: |
| 686 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 687 | <pre> |
| 688 | const ( // iota is set to 0 |
| 689 | enum0 = iota; // sets enum0 to 0, etc. |
| 690 | enum1 = iota; |
| 691 | enum2 = iota |
| 692 | ) |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 693 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 694 | const ( |
| 695 | a = 1 << iota; // a == 1 (iota has been reset) |
| 696 | b = 1 << iota; // b == 2 |
| 697 | c = 1 << iota; // c == 4 |
| 698 | ) |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 699 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 700 | const ( |
| 701 | u = iota * 42; // u == 0 (ideal integer) |
| 702 | v float = iota * 42; // v == 42.0 (float) |
| 703 | w = iota * 42; // w == 84 (ideal integer) |
| 704 | ) |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 705 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 706 | const x = iota; // x == 0 (iota has been reset) |
| 707 | const y = iota; // y == 0 (iota has been reset) |
| 708 | </pre> |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 709 | |
| 710 | Within an ExpressionList, the value of all "iota"'s is the same because "iota" |
| 711 | is only incremented at each semicolon: |
| 712 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 713 | <pre> |
| 714 | const ( |
| 715 | base0, mask0 int64 = 1 << iota, i << iota - 1; // base0 == 1, mask0 = 0 |
| 716 | base1, mask1 int64 = 1 << iota, i << iota - 1; // base1 == 2, mask1 = 1 |
| 717 | base2, mask2 int64 = 1 << iota, i << iota - 1; // base2 == 4, mask2 = 3 |
| 718 | ) |
| 719 | </pre> |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 720 | |
| 721 | Since the ExpressionList in constant declarations repeats implicitly |
| 722 | if omitted, some of the examples above can be abbreviated: |
| 723 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 724 | <pre> |
| 725 | const ( |
| 726 | enum0 = iota; |
| 727 | enum1; |
| 728 | enum2 |
| 729 | ) |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 730 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 731 | const ( |
| 732 | a = 1 << iota; |
| 733 | b; |
| 734 | c; |
| 735 | ) |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 736 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 737 | const ( |
| 738 | u = iota * 42; |
| 739 | v float; |
| 740 | w; |
| 741 | ) |
Robert Griesemer | 7354b86 | 2008-12-04 17:33:37 -0800 | [diff] [blame] | 742 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 743 | const ( |
| 744 | base0, mask0 int64 = 1 << iota, i << iota - 1; |
| 745 | base1, mask1 int64; |
| 746 | base2, mask2 int64; |
| 747 | ) |
| 748 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 749 | |
| 750 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 751 | <h3>Type declarations</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 752 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 753 | A type declaration specifies a new type and binds an identifier to it. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 754 | The identifier is called the ``type name''; it denotes the type. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 755 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 756 | <pre> |
| 757 | TypeDecl = "type" ( TypeSpec | "(" [ TypeSpecList ] ")" ) . |
| 758 | TypeSpecList = TypeSpec { ";" TypeSpec } [ ";" ] . |
| 759 | TypeSpec = identifier Type . |
| 760 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 761 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 762 | A struct or interface type may be forward-declared (§Struct types, |
| 763 | §Interface types). A forward-declared type is incomplete (§Types) |
| 764 | until it is fully declared. The full declaration must must follow |
| 765 | within the same block containing the forward declaration. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 766 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 767 | <pre> |
| 768 | type IntArray [16] int |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 769 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 770 | type ( |
| 771 | Point struct { x, y float }; |
| 772 | Polar Point |
| 773 | ) |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 774 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 775 | type TreeNode struct { |
| 776 | left, right *TreeNode; |
| 777 | value Point; |
| 778 | } |
| 779 | |
| 780 | type Comparable interface { |
| 781 | cmp(Comparable) int |
| 782 | } |
| 783 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 784 | |
| 785 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 786 | <h3>Variable declarations</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 787 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 788 | A variable declaration creates a variable, binds an identifier to it and |
| 789 | gives it a type. It may optionally give the variable an initial value. |
| 790 | The variable type must be a complete type (§Types). |
| 791 | In some forms of declaration the type of the initial value defines the type |
| 792 | of the variable. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 793 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 794 | <pre> |
| 795 | VarDecl = "var" ( VarSpec | "(" [ VarSpecList ] ")" ) . |
| 796 | VarSpecList = VarSpec { ";" VarSpec } [ ";" ] . |
| 797 | VarSpec = IdentifierList ( CompleteType [ "=" ExpressionList ] | "=" ExpressionList ) . |
| 798 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 799 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 800 | <pre> |
| 801 | var i int |
| 802 | var U, V, W float |
| 803 | var k = 0 |
| 804 | var x, y float = -1.0, -2.0 |
| 805 | var ( |
| 806 | i int; |
| 807 | u, v, s = 2.0, 3.0, "bar" |
| 808 | ) |
| 809 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 810 | |
| 811 | If the expression list is present, it must have the same number of elements |
| 812 | as there are variables in the variable specification. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 813 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 814 | If the variable type is omitted, an initialization expression (or expression |
| 815 | list) must be present, and the variable type is the type of the expression |
| 816 | value (in case of a list of variables, the variables assume the types of the |
| 817 | corresponding expression values). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 818 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 819 | If the variable type is omitted, and the corresponding initialization expression |
| 820 | is a constant expression of abstract int or floating point type, the type |
| 821 | of the variable is "int" or "float" respectively: |
| 822 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 823 | <pre> |
| 824 | var i = 0 // i has int type |
| 825 | var f = 3.1415 // f has float type |
| 826 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 827 | |
| 828 | The syntax |
| 829 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 830 | <pre> |
| 831 | SimpleVarDecl = IdentifierList ":=" ExpressionList . |
| 832 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 833 | |
| 834 | is shorthand for |
| 835 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 836 | <pre> |
| 837 | "var" IdentifierList = ExpressionList . |
| 838 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 839 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 840 | <pre> |
| 841 | i, j := 0, 10; |
| 842 | f := func() int { return 7; } |
| 843 | ch := new(chan int); |
| 844 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 845 | |
| 846 | Also, in some contexts such as "if", "for", or "switch" statements, |
| 847 | this construct can be used to declare local temporary variables. |
| 848 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 849 | <hr> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 850 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 851 | <h2>Types</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 852 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 853 | A type specifies the set of values that variables of that type may assume |
| 854 | and the operators that are applicable. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 855 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 856 | A type may be specified by a type name (§Type declarations) or a type literal. |
| 857 | A type literal is a syntactic construct that explicitly specifies the |
| 858 | composition of a new type in terms of other (already declared) types. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 859 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 860 | <pre> |
| 861 | Type = TypeName | TypeLit . |
| 862 | TypeName = QualifiedIdent. |
| 863 | TypeLit = |
| 864 | ArrayType | StructType | PointerType | FunctionType | InterfaceType | |
| 865 | SliceType | MapType | ChannelType . |
| 866 | </pre> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 867 | |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 868 | Some types are predeclared and denoted by their type names; these are called |
| 869 | ``basic types''. Generally (except for strings) they are not composed of more |
| 870 | elementary types; instead they model elementary machine data types. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 871 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 872 | All other types are called ``composite types'; they are composed from other |
| 873 | (basic or composite) types and denoted by their type names or by type literals. |
| 874 | There are arrays, structs, pointers, functions, interfaces, slices, maps, and |
| 875 | channels. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 876 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 877 | At a given point in the source code, a type may be ``complete'' or |
| 878 | ''incomplete''. Array and struct types are complete when they are fully declared. |
| 879 | All other types are always complete (although their components, such as the base |
| 880 | type of a pointer type, may be incomplete). Incomplete types are subject to usage |
| 881 | restrictions; for instance the type of a variable must be complete where the |
| 882 | variable is declared. |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 883 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 884 | <pre> |
| 885 | CompleteType = Type . |
| 886 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 887 | |
Robert Griesemer | a1065fa | 2008-09-29 20:37:46 -0700 | [diff] [blame] | 888 | The ``interface'' of a type is the set of methods bound to it |
| 889 | (§Method declarations). The interface of a pointer type is the interface |
| 890 | of the pointer base type (§Pointer types). All types have an interface; |
| 891 | if they have no methods associated with them, their interface is |
| 892 | called the ``empty'' interface. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 893 | <p> |
Robert Griesemer | a1065fa | 2008-09-29 20:37:46 -0700 | [diff] [blame] | 894 | The ``static type'' (or simply ``type'') of a variable is the type defined by |
| 895 | the variable's declaration. The ``dynamic type'' of a variable is the actual |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 896 | type of the value stored in a variable at run-time. Except for variables of |
Robert Griesemer | a1065fa | 2008-09-29 20:37:46 -0700 | [diff] [blame] | 897 | interface type, the dynamic type of a variable is always its static type. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 898 | <p> |
Robert Griesemer | a1065fa | 2008-09-29 20:37:46 -0700 | [diff] [blame] | 899 | Variables of interface type may hold values with different dynamic types |
| 900 | during execution. However, its dynamic type is always compatible with |
| 901 | the static type of the interface variable (§Interface types). |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 902 | |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 903 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 904 | <h3>Basic types</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 905 | |
| 906 | Go defines a number of basic types, referred to by their predeclared |
| 907 | type names. These include traditional arithmetic types, booleans, |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 908 | and strings. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 909 | |
| 910 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 911 | <h3>Arithmetic types</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 912 | |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 913 | The following list enumerates all platform-independent numeric types: |
| 914 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 915 | <pre> |
| 916 | byte same as uint8 (for convenience) |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 917 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 918 | uint8 the set of all unsigned 8-bit integers (0 to 255) |
| 919 | uint16 the set of all unsigned 16-bit integers (0 to 65535) |
| 920 | uint32 the set of all unsigned 32-bit integers (0 to 4294967295) |
| 921 | uint64 the set of all unsigned 64-bit integers (0 to 18446744073709551615) |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 922 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 923 | int8 the set of all signed 8-bit integers (-128 to 127) |
| 924 | int16 the set of all signed 16-bit integers (-32768 to 32767) |
| 925 | int32 the set of all signed 32-bit integers (-2147483648 to 2147483647) |
| 926 | int64 the set of all signed 64-bit integers (-9223372036854775808 to 9223372036854775807) |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 927 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 928 | float32 the set of all valid IEEE-754 32-bit floating point numbers |
| 929 | float64 the set of all valid IEEE-754 64-bit floating point numbers |
| 930 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 931 | |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 932 | Integer types are represented in the usual binary format; the value of |
| 933 | an n-bit integer is n bits wide. A negative signed integer is represented |
| 934 | as the two's complement of its absolute value. |
| 935 | |
| 936 | <!-- |
| 937 | The representation of signed integers and their exact range is |
| 938 | implementation-specific, but the set of all positive values (including zero) |
| 939 | of a signed integer type is always a subset of the corresponding unsigned |
| 940 | integer type (thus, a positive signed integer can always be converted into |
| 941 | its corresponding unsigned type without loss). |
| 942 | --> |
| 943 | |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 944 | Additionally, Go declares a set of platform-specific numeric types for |
| 945 | convenience: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 946 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 947 | <pre> |
| 948 | uint at least 32 bits, at most the size of the largest uint type |
| 949 | int at least 32 bits, at most the size of the largest int type |
| 950 | float at least 32 bits, at most the size of the largest float type |
| 951 | uintptr smallest uint type large enough to store the uninterpreted |
| 952 | bits of a pointer value |
| 953 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 954 | |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 955 | For instance, int might have the same size as int32 on a 32-bit |
| 956 | architecture, or int64 on a 64-bit architecture. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 957 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 958 | Except for "byte", which is an alias for "uint8", all numeric types |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 959 | are different from each other to avoid portability issues. Conversions |
| 960 | are required when different numeric types are mixed in an expression or assignment. |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 961 | For instance, "int32" and "int" are not the same type even though they may have |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 962 | the same size on a particular platform. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 963 | |
| 964 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 965 | <h3>Booleans</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 966 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 967 | The type "bool" comprises the truth values true and false, which are |
| 968 | available through the two predeclared constants, "true" and "false". |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 969 | |
| 970 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 971 | <h3>Strings</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 972 | |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 973 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 974 | The "string" type represents the set of string values (strings). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 975 | Strings behave like arrays of bytes, with the following properties: |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 976 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 977 | <ul> |
| 978 | <li>They are immutable: after creation, it is not possible to change the |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 979 | contents of a string. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 980 | <li>No internal pointers: it is illegal to create a pointer to an inner |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 981 | element of a string. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 982 | <li>They can be indexed: given string "s1", "s1[i]" is a byte value. |
| 983 | <li>They can be concatenated: given strings "s1" and "s2", "s1 + s2" is a value |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 984 | combining the elements of "s1" and "s2" in sequence. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 985 | <li>Known length: the length of a string "s1" can be obtained by calling |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 986 | "len(s1)". The length of a string is the number |
| 987 | of bytes within. Unlike in C, there is no terminal NUL byte. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 988 | <li>Creation 1: a string can be created from an integer value by a conversion; |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 989 | the result is a string containing the UTF-8 encoding of that code point |
| 990 | (§Conversions). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 991 | "string('x')" yields "x"; "string(0x1234)" yields the equivalent of "\u1234" |
| 992 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 993 | <li>Creation 2: a string can by created from an array of integer values (maybe |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 994 | just array of bytes) by a conversion (§Conversions): |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 995 | <pre> |
| 996 | a [3]byte; a[0] = 'a'; a[1] = 'b'; a[2] = 'c'; string(a) == "abc"; |
| 997 | </pre> |
| 998 | </ul> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 999 | |
| 1000 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1001 | <h3>Array types</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1002 | |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1003 | An array is a composite type consisting of a number of elements all of the |
| 1004 | same type, called the element type. The element type must be a complete type |
| 1005 | (§Types). The number of elements of an array is called its length; it is never |
| 1006 | negative. The elements of an array are designated by indices |
| 1007 | which are integers from 0 through the length - 1. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1008 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1009 | <pre> |
| 1010 | ArrayType = "[" ArrayLength "]" ElementType . |
| 1011 | ArrayLength = Expression . |
| 1012 | ElementType = CompleteType . |
| 1013 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1014 | |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1015 | The array length and its value are part of the array type. The array length |
| 1016 | must be a constant expression (§Constant expressions) that evaluates to an |
| 1017 | integer value >= 0. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1018 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1019 | The number of elements of an array "a" can be discovered using the built-in |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1020 | function |
| 1021 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1022 | <pre> |
| 1023 | len(a) |
| 1024 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1025 | |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1026 | The length of arrays is known at compile-time, and the result of a call to |
| 1027 | "len(a)" is a compile-time constant. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1028 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1029 | <pre> |
| 1030 | [32]byte |
| 1031 | [2*N] struct { x, y int32 } |
| 1032 | [1000]*float64 |
| 1033 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1034 | |
Robert Griesemer | 1593ab6 | 2009-01-16 15:36:46 -0800 | [diff] [blame] | 1035 | Assignment compatibility: Arrays can be assigned to variables of equal type |
| 1036 | and to slice variables with equal element type. When assigning to a slice |
| 1037 | variable, the array is not copied but a slice comprising the entire array |
| 1038 | is created. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1039 | |
| 1040 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1041 | <h3>Struct types</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1042 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 1043 | A struct is a composite type consisting of a fixed number of elements, |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1044 | called fields, with possibly different types. A struct type declares |
| 1045 | an identifier and type for each field. Within a struct type no field |
| 1046 | identifier may be declared twice and all field types must be complete |
| 1047 | types (§Types). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1048 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1049 | <pre> |
| 1050 | StructType = "struct" [ "{" [ FieldDeclList ] "}" ] . |
| 1051 | FieldDeclList = FieldDecl { ";" FieldDecl } [ ";" ] . |
| 1052 | FieldDecl = (IdentifierList CompleteType | [ "*" ] TypeName) [ Tag ] . |
| 1053 | Tag = StringLit . |
| 1054 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1055 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1056 | <pre> |
| 1057 | // An empty struct. |
| 1058 | struct {} |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1059 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1060 | // A struct with 5 fields. |
| 1061 | struct { |
| 1062 | x, y int; |
| 1063 | u float; |
| 1064 | A *[]int; |
| 1065 | F func(); |
| 1066 | } |
| 1067 | </pre> |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 1068 | |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1069 | A struct may contain ``anonymous fields'', which are declared with a type |
| 1070 | but no explicit field identifier. An anonymous field type must be specified as |
| 1071 | a type name "T", or as a pointer to a type name ``*T'', and T itself may not be |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 1072 | a pointer or interface type. The unqualified type name acts as the field identifier. |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 1073 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1074 | <pre> |
| 1075 | // A struct with four anonymous fields of type T1, *T2, P.T3 and *P.T4 |
| 1076 | struct { |
| 1077 | T1; // the field name is T1 |
| 1078 | *T2; // the field name is T2 |
| 1079 | P.T3; // the field name is the unqualified type name T3 |
| 1080 | *P.T4; // the field name is the unqualified type name T4 |
| 1081 | x, y int; |
| 1082 | } |
| 1083 | </pre> |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 1084 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1085 | The unqualified type name of an anonymous field must not conflict with the |
| 1086 | field identifier (or unqualified type name for an anonymous field) of any |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1087 | other field within the struct. The following declaration is illegal: |
| 1088 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1089 | <pre> |
| 1090 | struct { |
| 1091 | T; // conflicts with anonymous field *T and *P.T |
| 1092 | *T; // conflicts with anonymous field T and *P.T |
| 1093 | *P.T; // conflicts with anonymous field T and *T |
| 1094 | } |
| 1095 | </pre> |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 1096 | |
Robert Griesemer | c59b2a3 | 2008-09-30 10:57:59 -0700 | [diff] [blame] | 1097 | Fields and methods (§Method declarations) of an anonymous field become directly |
| 1098 | accessible as fields and methods of the struct without the need to provide the |
Robert Griesemer | a6b546f | 2008-10-20 11:46:40 -0700 | [diff] [blame] | 1099 | type name of the respective anonymous field (§Selectors). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1100 | <p> |
Robert Griesemer | 2e90e54 | 2008-10-30 15:52:37 -0700 | [diff] [blame] | 1101 | A field declaration may be followed by an optional string literal tag which |
| 1102 | becomes an ``attribute'' for all the identifiers in the corresponding |
| 1103 | field declaration. The tags are available via the reflection library but |
| 1104 | are ignored otherwise. A tag may contain arbitrary application-specific |
Robert Griesemer | f618f89 | 2008-11-03 10:52:28 -0800 | [diff] [blame] | 1105 | information. |
Robert Griesemer | 2e90e54 | 2008-10-30 15:52:37 -0700 | [diff] [blame] | 1106 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1107 | <pre> |
| 1108 | // A struct corresponding to the EventIdMessage protocol buffer. |
| 1109 | // The tag strings contain the protocol buffer field tags. |
| 1110 | struct { |
| 1111 | time_usec uint64 "1"; |
| 1112 | server_ip uint32 "2"; |
| 1113 | process_id uint32 "3"; |
| 1114 | } |
| 1115 | </pre> |
Robert Griesemer | 2e90e54 | 2008-10-30 15:52:37 -0700 | [diff] [blame] | 1116 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1117 | Forward declaration: |
| 1118 | A struct type consisting of only the reserved word "struct" may be used in |
| 1119 | a type declaration; it declares an incomplete struct type (§Type declarations). |
| 1120 | This allows the construction of mutually recursive types such as: |
| 1121 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1122 | <pre> |
| 1123 | type S2 struct // forward declaration of S2 |
| 1124 | type S1 struct { s2 *S2 } |
| 1125 | type S2 struct { s1 *S1 } |
| 1126 | </pre> |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1127 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 1128 | Assignment compatibility: Structs are assignment compatible to variables of |
| 1129 | equal type only. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1130 | |
| 1131 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1132 | <h3>Pointer types</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1133 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 1134 | A pointer type denotes the set of all pointers to variables of a given |
| 1135 | type, called the ``base type'' of the pointer, and the value "nil". |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1136 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1137 | <pre> |
| 1138 | PointerType = "*" BaseType . |
| 1139 | BaseType = Type . |
| 1140 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1141 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1142 | <pre> |
| 1143 | *int |
| 1144 | map[string] chan |
| 1145 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1146 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1147 | The pointer base type may be denoted by an identifier referring to an |
| 1148 | incomplete type (§Types), possibly declared via a forward declaration. |
| 1149 | This allows the construction of recursive and mutually recursive types |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1150 | such as: |
| 1151 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1152 | <pre> |
| 1153 | type S struct { s *S } |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1154 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1155 | type S2 struct // forward declaration of S2 |
| 1156 | type S1 struct { s2 *S2 } |
| 1157 | type S2 struct { s1 *S1 } |
| 1158 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1159 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 1160 | Assignment compatibility: A pointer is assignment compatible to a variable |
| 1161 | of pointer type, only if both types are equal. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1162 | <p> |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 1163 | Comparisons: A variable of pointer type can be compared against "nil" with the |
| 1164 | operators "==" and "!=" (§Comparison operators). The variable is |
| 1165 | "nil" only if "nil" is assigned explicitly to the variable (§Assignments), or |
| 1166 | if the variable has not been modified since creation (§Program initialization |
| 1167 | and execution). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1168 | <p> |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 1169 | Two variables of equal pointer type can be tested for equality with the |
| 1170 | operators "==" and "!=" (§Comparison operators). The pointers are equal |
| 1171 | if they point to the same location. |
| 1172 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 1173 | Pointer arithmetic of any kind is not permitted. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1174 | |
| 1175 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1176 | <h3>Function types</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1177 | |
Robert Griesemer | 7231ceb | 2008-09-08 15:01:04 -0700 | [diff] [blame] | 1178 | A function type denotes the set of all functions with the same parameter |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 1179 | and result types, and the value "nil". |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1180 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1181 | <pre> |
| 1182 | FunctionType = "func" Signature . |
| 1183 | Signature = "(" [ ParameterList ] ")" [ Result ] . |
| 1184 | ParameterList = ParameterDecl { "," ParameterDecl } . |
| 1185 | ParameterDecl = [ IdentifierList ] ( Type | "..." ) . |
| 1186 | Result = Type | "(" ParameterList ")" . |
| 1187 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1188 | |
Robert Griesemer | ac05579 | 2008-09-26 11:15:14 -0700 | [diff] [blame] | 1189 | In ParameterList, the parameter names (IdentifierList) either must all be |
| 1190 | present, or all be absent. If the parameters are named, each name stands |
| 1191 | for one parameter of the specified type. If the parameters are unnamed, each |
| 1192 | type stands for one parameter of that type. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1193 | <p> |
Robert Griesemer | 2bfa957 | 2008-10-24 13:13:12 -0700 | [diff] [blame] | 1194 | For the last incoming parameter only, instead of a parameter type one |
| 1195 | may write "...". The ellipsis indicates that the last parameter stands |
| 1196 | for an arbitrary number of additional arguments of any type (including |
| 1197 | no additional arguments). If the parameters are named, the identifier |
| 1198 | list immediately preceding "..." must contain only one identifier (the |
| 1199 | name of the last parameter). |
| 1200 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1201 | <pre> |
| 1202 | func () |
| 1203 | func (x int) |
| 1204 | func () int |
| 1205 | func (string, float, ...) |
| 1206 | func (a, b int, z float) bool |
| 1207 | func (a, b int, z float) (bool) |
| 1208 | func (a, b int, z float, opt ...) (success bool) |
| 1209 | func (int, int, float) (float, *[]int) |
| 1210 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1211 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 1212 | If the result type of a function is itself a function type, the result type |
| 1213 | must be parenthesized to resolve a parsing ambiguity: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1214 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1215 | <pre> |
| 1216 | func (n int) (func (p* T)) |
| 1217 | </pre> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 1218 | |
| 1219 | Assignment compatibility: A function can be assigned to a function |
| 1220 | variable only if both function types are equal. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1221 | <p> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 1222 | Comparisons: A variable of function type can be compared against "nil" with the |
| 1223 | operators "==" and "!=" (§Comparison operators). The variable is |
| 1224 | "nil" only if "nil" is assigned explicitly to the variable (§Assignments), or |
| 1225 | if the variable has not been modified since creation (§Program initialization |
| 1226 | and execution). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1227 | <p> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 1228 | Two variables of equal function type can be tested for equality with the |
| 1229 | operators "==" and "!=" (§Comparison operators). The variables are equal |
| 1230 | if they refer to the same function. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1231 | |
| 1232 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1233 | <h3>Interface types</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1234 | |
Robert Griesemer | a1065fa | 2008-09-29 20:37:46 -0700 | [diff] [blame] | 1235 | Type interfaces may be specified explicitly by interface types. |
| 1236 | An interface type denotes the set of all types that implement at least |
| 1237 | the set of methods specified by the interface type, and the value "nil". |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1238 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1239 | <pre> |
| 1240 | InterfaceType = "interface" [ "{" [ MethodSpecList ] "}" ] . |
| 1241 | MethodSpecList = MethodSpec { ";" MethodSpec } [ ";" ] . |
| 1242 | MethodSpec = IdentifierList Signature | TypeName . |
| 1243 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1244 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1245 | <pre> |
| 1246 | // An interface specifying a basic File type. |
| 1247 | interface { |
| 1248 | Read, Write (b Buffer) bool; |
| 1249 | Close (); |
| 1250 | } |
| 1251 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1252 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1253 | Any type (including interface types) whose interface has, possibly as a |
| 1254 | subset, the complete set of methods of an interface I is said to implement |
| 1255 | interface I. For instance, if two types S1 and S2 have the methods |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1256 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1257 | <pre> |
| 1258 | func (p T) Read(b Buffer) bool { return ... } |
| 1259 | func (p T) Write(b Buffer) bool { return ... } |
| 1260 | func (p T) Close() { ... } |
| 1261 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1262 | |
| 1263 | (where T stands for either S1 or S2) then the File interface is |
| 1264 | implemented by both S1 and S2, regardless of what other methods |
| 1265 | S1 and S2 may have or share. |
| 1266 | |
| 1267 | All types implement the empty interface: |
| 1268 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1269 | <pre> |
| 1270 | interface {} |
| 1271 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1272 | |
| 1273 | In general, a type implements an arbitrary number of interfaces. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1274 | For instance, consider the interface |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1275 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1276 | <pre> |
| 1277 | type Lock interface { |
| 1278 | Lock, Unlock (); |
| 1279 | } |
| 1280 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1281 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1282 | If S1 and S2 also implement |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1283 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1284 | <pre> |
| 1285 | func (p T) Lock() { ... } |
| 1286 | func (p T) Unlock() { ... } |
| 1287 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1288 | |
| 1289 | they implement the Lock interface as well as the File interface. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1290 | <p> |
Robert Griesemer | 38c232f | 2009-02-11 15:09:15 -0800 | [diff] [blame] | 1291 | An interface may contain a type name T in place of a method specification. |
| 1292 | T must denote another, complete (and not forward-declared) interface type. |
| 1293 | Using this notation is equivalent to enumerating the methods of T explicitly |
| 1294 | in the interface containing T. |
| 1295 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1296 | <pre> |
| 1297 | type ReadWrite interface { |
| 1298 | Read, Write (b Buffer) bool; |
| 1299 | } |
Robert Griesemer | 38c232f | 2009-02-11 15:09:15 -0800 | [diff] [blame] | 1300 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1301 | type File interface { |
| 1302 | ReadWrite; // same as enumerating the methods in ReadWrite |
| 1303 | Lock; // same as enumerating the methods in Lock |
| 1304 | Close(); |
| 1305 | } |
| 1306 | </pre> |
Robert Griesemer | 38c232f | 2009-02-11 15:09:15 -0800 | [diff] [blame] | 1307 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1308 | Forward declaration: |
| 1309 | A interface type consisting of only the reserved word "interface" may be used in |
| 1310 | a type declaration; it declares an incomplete interface type (§Type declarations). |
| 1311 | This allows the construction of mutually recursive types such as: |
| 1312 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1313 | <pre> |
| 1314 | type T2 interface |
| 1315 | type T1 interface { |
| 1316 | foo(T2) int; |
| 1317 | } |
| 1318 | type T2 interface { |
| 1319 | bar(T1) int; |
| 1320 | } |
| 1321 | </pre> |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1322 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1323 | Assignment compatibility: A value can be assigned to an interface variable |
Robert Griesemer | b5e0cc7 | 2008-10-10 16:34:44 -0700 | [diff] [blame] | 1324 | if the static type of the value implements the interface or if the value is "nil". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1325 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1326 | Comparisons: A variable of interface type can be compared against "nil" with the |
| 1327 | operators "==" and "!=" (§Comparison operators). The variable is |
| 1328 | "nil" only if "nil" is assigned explicitly to the variable (§Assignments), or |
| 1329 | if the variable has not been modified since creation (§Program initialization |
| 1330 | and execution). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1331 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1332 | Two variables of interface type can be tested for equality with the |
| 1333 | operators "==" and "!=" (§Comparison operators) if both variables have the |
| 1334 | same static type. They are equal if both their dynamic types and values are |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 1335 | equal. If the dynamic types are equal but the values do not support comparison, |
| 1336 | a run-time error occurs. |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1337 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1338 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1339 | <h3>Slice types</h3> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1340 | |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 1341 | A slice type denotes the set of all slices (segments) of arrays |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1342 | (§Array types) of a given element type, and the value "nil". |
| 1343 | The number of elements of a slice is called its length; it is never negative. |
| 1344 | The elements of a slice are designated by indices which are |
| 1345 | integers from 0 through the length - 1. |
| 1346 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1347 | <pre> |
| 1348 | SliceType = "[" "]" ElementType . |
| 1349 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1350 | |
| 1351 | Syntactically and semantically, arrays and slices look and behave very |
| 1352 | similarly, but with one important difference: A slice is a descriptor |
| 1353 | of an array segment; in particular, different variables of a slice type may |
| 1354 | refer to different (and possibly overlapping) segments of the same underlying |
| 1355 | array. Thus, with respect to the underlying array, slices behave like |
| 1356 | references. In contrast, two different variables of array type always |
| 1357 | denote two different arrays. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1358 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1359 | For slices, the actual array underlying the slice may extend past the current |
| 1360 | slice length; the maximum length a slice may assume is called its capacity. |
| 1361 | The capacity of any slice "a" can be discovered using the built-in function |
| 1362 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1363 | <pre> |
| 1364 | cap(a) |
| 1365 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1366 | |
| 1367 | and the following relationship between "len()" and "cap()" holds: |
| 1368 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1369 | <pre> |
| 1370 | 0 <= len(a) <= cap(a) |
| 1371 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1372 | |
| 1373 | The value of an uninitialized slice is "nil", and its length and capacity |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 1374 | are 0. A new, initialized slice value for a given element type T is |
| 1375 | made using the built-in function "make", which takes a slice type |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1376 | and parameters specifying the length and optionally the capacity: |
| 1377 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1378 | <pre> |
| 1379 | make([]T, length) |
| 1380 | make([]T, length, capacity) |
| 1381 | </pre> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 1382 | |
| 1383 | The "make()" call allocates a new underlying array to which the returned |
| 1384 | slice value refers. More precisely, calling "make" |
| 1385 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1386 | <pre> |
| 1387 | make([]T, length, capacity) |
| 1388 | </pre> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 1389 | |
| 1390 | is effectively the same as allocating an array and slicing it |
| 1391 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1392 | <pre> |
| 1393 | new([capacity]T)[0 : length] |
| 1394 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1395 | |
| 1396 | Assignment compatibility: Slices are assignment compatible to variables |
| 1397 | of the same type. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1398 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1399 | Indexing: Given a (pointer to) a slice variable "a", a slice element is |
| 1400 | specified with an index operation: |
| 1401 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1402 | <pre> |
| 1403 | a[i] |
| 1404 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1405 | |
| 1406 | This denotes the slice element at index "i". "i" must be within bounds, |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1407 | that is "0 <= i < len(a)". |
| 1408 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1409 | Slicing: Given a a slice variable "a", a sub-slice is created with a slice |
| 1410 | operation: |
| 1411 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1412 | <pre> |
| 1413 | a[i : j] |
| 1414 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1415 | |
| 1416 | This creates the sub-slice consisting of the elements "a[i]" through "a[j - 1]" |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1417 | (that is, excluding "a[j]"). The values "i" and "j" must satisfy the condition |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1418 | "0 <= i <= j <= cap(a)". The length of the new slice is "j - i". The capacity of |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1419 | the slice is "cap(a) - i"; thus if "i" is 0, the slice capacity does not change |
| 1420 | as a result of a slice operation. The type of a sub-slice is the same as the |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1421 | type of the slice. Unlike the capacity, the length of a sub-slice may be larger |
| 1422 | than the length of the original slice. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1423 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1424 | Comparisons: A variable of slice type can be compared against "nil" with the |
| 1425 | operators "==" and "!=" (§Comparison operators). The variable is |
| 1426 | "nil" only if "nil" is assigned explicitly to the variable (§Assignments), or |
| 1427 | if the variable has not been modified since creation (§Program initialization |
| 1428 | and execution). |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1429 | |
| 1430 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1431 | <h3>Map types</h3> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1432 | |
| 1433 | A map is a composite type consisting of a variable number of entries |
| 1434 | called (key, value) pairs. For a given map, the keys and values must |
| 1435 | each be of a specific complete type (§Types) called the key and value type, |
| 1436 | respectively. The number of entries in a map is called its length; it is never |
| 1437 | negative. |
| 1438 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1439 | <pre> |
| 1440 | MapType = "map" "[" KeyType "]" ValueType . |
| 1441 | KeyType = CompleteType . |
| 1442 | ValueType = CompleteType . |
| 1443 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1444 | |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 1445 | The comparison operators "==" and "!=" (§Comparison operators) must be defined |
| 1446 | for operands of the key type; thus the key type must be a basic, pointer, |
| 1447 | interface, or channel type. If the key type is an interface type, |
| 1448 | the dynamic key types must support these comparison operators. In this case, |
| 1449 | inserting a map value with a key that does not support testing for equality |
| 1450 | is a run-time error. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1451 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1452 | Upon creation, a map is empty and values may be added and removed |
| 1453 | during execution. |
| 1454 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1455 | <pre> |
| 1456 | map [string] int |
| 1457 | map [*T] struct { x, y float } |
| 1458 | map [string] interface {} |
| 1459 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1460 | |
| 1461 | The length of a map "m" can be discovered using the built-in function |
| 1462 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1463 | <pre> |
| 1464 | len(m) |
| 1465 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1466 | |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 1467 | The value of an uninitialized map is "nil". A new, empty map value for given |
| 1468 | map type M is made using the built-in function "make" which takes the map type |
| 1469 | and an optional capacity as arguments: |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1470 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1471 | <pre> |
| 1472 | my_map := make(M, 100); |
| 1473 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1474 | |
| 1475 | The map capacity is an allocation hint for more efficient incremental growth |
| 1476 | of the map. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1477 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1478 | Assignment compatibility: A map type is assignment compatible to a variable of |
| 1479 | map type only if both types are equal. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1480 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1481 | Comparisons: A variable of map type can be compared against "nil" with the |
| 1482 | operators "==" and "!=" (§Comparison operators). The variable is |
| 1483 | "nil" only if "nil" is assigned explicitly to the variable (§Assignments), or |
| 1484 | if the variable has not been modified since creation (§Program initialization |
| 1485 | and execution). |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1486 | |
| 1487 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1488 | <h3>Channel types</h3> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1489 | |
| 1490 | A channel provides a mechanism for two concurrently executing functions |
| 1491 | to synchronize execution and exchange values of a specified type. This |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1492 | type must be a complete type (§Types). <font color=red>(TODO could it be incomplete?)</font> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1493 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1494 | <pre> |
| 1495 | ChannelType = Channel | SendChannel | RecvChannel . |
| 1496 | Channel = "chan" ValueType . |
| 1497 | SendChannel = "chan" "<-" ValueType . |
| 1498 | RecvChannel = "<-" "chan" ValueType . |
| 1499 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1500 | |
| 1501 | Upon creation, a channel can be used both to send and to receive. |
| 1502 | By conversion or assignment, a channel may be constrained only to send or |
| 1503 | to receive. This constraint is called a channel's ``direction''; either |
| 1504 | bi-directional (unconstrained), send, or receive. |
| 1505 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1506 | <pre> |
| 1507 | chan T // can send and receive values of type T |
| 1508 | chan <- float // can only be used to send floats |
| 1509 | <-chan int // can only receive ints |
| 1510 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1511 | |
| 1512 | The value of an uninitialized channel is "nil". A new, initialized channel |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 1513 | value for a given element type T is made using the built-in function "make", |
| 1514 | which takes the channel type and an optional capacity as arguments: |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1515 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1516 | <pre> |
| 1517 | my_chan = make(chan int, 100); |
| 1518 | </pre> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1519 | |
| 1520 | The capacity sets the size of the buffer in the communication channel. If the |
| 1521 | capacity is greater than zero, the channel is asynchronous and, provided the |
| 1522 | buffer is not full, sends can succeed without blocking. If the capacity is zero, |
| 1523 | the communication succeeds only when both a sender and receiver are ready. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1524 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1525 | Assignment compatibility: A value of type channel can be assigned to a variable |
| 1526 | of type channel only if a) both types are equal (§Type equality), or b) both |
| 1527 | have equal channel value types and the value is a bidirectional channel. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1528 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1529 | Comparisons: A variable of channel type can be compared against "nil" with the |
| 1530 | operators "==" and "!=" (§Comparison operators). The variable is |
| 1531 | "nil" only if "nil" is assigned explicitly to the variable (§Assignments), or |
| 1532 | if the variable has not been modified since creation (§Program initialization |
| 1533 | and execution). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1534 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 1535 | Two variables of channel type can be tested for equality with the |
| 1536 | operators "==" and "!=" (§Comparison operators) if both variables have |
| 1537 | the same ValueType. They are equal if both values were created by the same |
| 1538 | "make" call (§Making slices, maps, and channels). |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1539 | |
| 1540 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1541 | <h3>Type equality</h3> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1542 | |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1543 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1544 | Types may be ``different'', ``structurally equal'', or ``identical''. |
| 1545 | Go is a type-safe language; generally different types cannot be mixed |
| 1546 | in binary operations, and values cannot be assigned to variables of different |
| 1547 | types. However, values may be assigned to variables of structually |
| 1548 | equal types. Finally, type guards succeed only if the dynamic type |
| 1549 | is identical to or implements the type tested against (§Type guards). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1550 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1551 | Structural type equality (equality for short) is defined by these rules: |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1552 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1553 | Two type names denote equal types if the types in the corresponding declarations |
| 1554 | are equal. Two type literals specify equal types if they have the same |
| 1555 | literal structure and corresponding components have equal types. Loosely |
| 1556 | speaking, two types are equal if their values have the same layout in memory. |
| 1557 | More precisely: |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1558 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1559 | <ul> |
| 1560 | <li>Two array types are equal if they have equal element types and if they |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1561 | have the same array length. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1562 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1563 | <li>Two struct types are equal if they have the same number of fields in the |
Robert Griesemer | 77ccfb0 | 2009-02-05 16:11:14 -0800 | [diff] [blame] | 1564 | same order, corresponding fields either have both the same name or |
| 1565 | are both anonymous, and corresponding field types are identical. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1566 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1567 | <li>Two pointer types are equal if they have equal base types. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1568 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1569 | <li>Two function types are equal if they have the same number of parameters |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1570 | and result values and if corresponding parameter and result types are |
| 1571 | equal (a "..." parameter is equal to another "..." parameter). |
| 1572 | Note that parameter and result names do not have to match. |
| 1573 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1574 | <li>Two slice types are equal if they have equal element types. |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1575 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1576 | <li>Two channel types are equal if they have equal value types and |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1577 | the same direction. |
| 1578 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1579 | <li>Two map types are equal if they have equal key and value types. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1580 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1581 | <li>Two interface types are equal if they have the same set of methods |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1582 | with the same names and equal function types. Note that the order |
| 1583 | of the methods in the respective type declarations is irrelevant. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1584 | </ul> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1585 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1586 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1587 | Type identity is defined by these rules: |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1588 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1589 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1590 | Two type names denote identical types if they originate in the same |
| 1591 | type declaration. Two type literals specify identical types if they have the |
| 1592 | same literal structure and corresponding components have identical types. |
| 1593 | More precisely: |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1594 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1595 | <ul> |
| 1596 | <li>Two array types are identical if they have identical element types and if |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1597 | they have the same array length. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1598 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1599 | <li>Two struct types are identical if they have the same number of fields in |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1600 | the same order, corresponding fields either have both the same name or |
| 1601 | are both anonymous, and corresponding field types are identical. |
| 1602 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1603 | <li>Two pointer types are identical if they have identical base types. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1604 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1605 | <li>Two function types are identical if they have the same number of |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1606 | parameters and result values both with the same (or absent) names, and |
| 1607 | if corresponding parameter and result types are identical (a "..." |
| 1608 | parameter is identical to another "..." parameter with the same name). |
| 1609 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1610 | <li>Two slice types are identical if they have identical element types. |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1611 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1612 | <li>Two channel types are identical if they have identical value types and |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1613 | the same direction. |
| 1614 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1615 | <li>Two map types are identical if they have identical key and value types. |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1616 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1617 | <li>Two interface types are identical if they have the same set of methods |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1618 | with the same names and identical function types. Note that the order |
| 1619 | of the methods in the respective type declarations is irrelevant. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1620 | </ul> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1621 | |
| 1622 | Note that the type denoted by a type name is identical only to the type literal |
| 1623 | in the type name's declaration. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1624 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1625 | Finally, two types are different if they are not structurally equal. |
| 1626 | (By definition, they cannot be identical, either). |
| 1627 | |
| 1628 | For instance, given the declarations |
| 1629 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1630 | <pre> |
| 1631 | type ( |
| 1632 | T0 []string; |
| 1633 | T1 []string |
| 1634 | T2 struct { a, b int }; |
| 1635 | T3 struct { a, c int }; |
| 1636 | T4 func (int, float) *T0 |
| 1637 | T5 func (x int, y float) *[]string |
| 1638 | ) |
| 1639 | </pre> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1640 | |
| 1641 | these are some types that are equal |
| 1642 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1643 | <pre> |
| 1644 | T0 and T0 |
| 1645 | T0 and []string |
| 1646 | T2 and T3 |
| 1647 | T4 and T5 |
| 1648 | T3 and struct { a int; int } |
| 1649 | </pre> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1650 | |
| 1651 | and these are some types that are identical |
| 1652 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1653 | <pre> |
| 1654 | T0 and T0 |
| 1655 | []int and []int |
| 1656 | struct { a, b *T5 } and struct { a, b *T5 } |
| 1657 | </pre> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1658 | |
| 1659 | As an example, "T0" and "T1" are equal but not identical because they have |
| 1660 | different declarations. |
| 1661 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1662 | <hr> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1663 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1664 | <h2>Expressions</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1665 | |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 1666 | An expression specifies the computation of a value via the application of |
| 1667 | operators and function invocations on operands. An expression has a value and |
| 1668 | a type. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1669 | <p> |
Robert Griesemer | c8e1876 | 2008-09-12 12:26:22 -0700 | [diff] [blame] | 1670 | The type of a constant expression may be an ideal number. The type of such expressions |
Robert Griesemer | 71696ac | 2008-10-16 15:03:22 -0700 | [diff] [blame] | 1671 | is implicitly converted into the 'expected numeric type' required for the expression. |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 1672 | The conversion is legal if the (ideal) expression value is a member of the |
Robert Griesemer | 71696ac | 2008-10-16 15:03:22 -0700 | [diff] [blame] | 1673 | set represented by the expected numeric type. In all other cases, and specifically |
| 1674 | if the expected type is not a numeric type, the expression is erroneous. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1675 | <p> |
Robert Griesemer | 71696ac | 2008-10-16 15:03:22 -0700 | [diff] [blame] | 1676 | For instance, if the expected numeric type is a uint32, any ideal number |
| 1677 | which fits into a uint32 without loss of precision can be legally converted. |
| 1678 | Thus, the values 991, 42.0, and 1e9 are ok, but -1, 3.14, or 1e100 are not. |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 1679 | |
Robert Griesemer | 71696ac | 2008-10-16 15:03:22 -0700 | [diff] [blame] | 1680 | <!-- |
Robert Griesemer | c8e1876 | 2008-09-12 12:26:22 -0700 | [diff] [blame] | 1681 | TODO(gri) This may be overly constraining. What about "len(a) + c" where |
| 1682 | c is an ideal number? Is len(a) of type int, or of an ideal number? Probably |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1683 | should be ideal number, because for arrays, it is a constant. |
Robert Griesemer | 71696ac | 2008-10-16 15:03:22 -0700 | [diff] [blame] | 1684 | --> |
Robert Griesemer | c8e1876 | 2008-09-12 12:26:22 -0700 | [diff] [blame] | 1685 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1686 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1687 | <h3>Operands</h3> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 1688 | |
| 1689 | Operands denote the elementary values in an expression. |
| 1690 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1691 | <pre> |
| 1692 | Operand = Literal | QualifiedIdent | "(" Expression ")" . |
| 1693 | Literal = BasicLit | CompositeLit | FunctionLit . |
| 1694 | BasicLit = int_lit | float_lit | char_lit | StringLit . |
| 1695 | StringLit = string_lit { string_lit } . |
| 1696 | </pre> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 1697 | |
| 1698 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1699 | <h3>Constants</h3> |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 1700 | |
| 1701 | An operand is called ``constant'' if it is a literal of a basic type |
Robert Griesemer | c59b2a3 | 2008-09-30 10:57:59 -0700 | [diff] [blame] | 1702 | (including the predeclared constants "true" and "false", and the values |
| 1703 | denoted by "iota"), the predeclared constant "nil", or a parenthesized |
| 1704 | constant expression (§Constant expressions). Constants have values that |
| 1705 | are known at compile-time. |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 1706 | |
| 1707 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1708 | <h3>Qualified identifiers</h3> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 1709 | |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 1710 | A qualified identifier is an identifier qualified by a package name. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1711 | <p> |
| 1712 | <font color=red> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 1713 | TODO(gri) expand this section. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1714 | </font> |
Robert Griesemer | 337af31 | 2008-11-17 18:11:36 -0800 | [diff] [blame] | 1715 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1716 | <pre> |
| 1717 | QualifiedIdent = { PackageName "." } identifier . |
| 1718 | PackageName = identifier . |
| 1719 | </pre> |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 1720 | |
| 1721 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1722 | <h3>Composite literals</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1723 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1724 | Literals for composite data structures consist of the type of the value |
Robert Griesemer | 91bbd64 | 2009-01-07 09:31:35 -0800 | [diff] [blame] | 1725 | followed by a braced expression list for array, slice, and structure literals, |
Robert Griesemer | 0976e34 | 2008-09-03 13:37:44 -0700 | [diff] [blame] | 1726 | or a list of expression pairs for map literals. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1727 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1728 | <pre> |
| 1729 | CompositeLit = LiteralType "(" [ ( ExpressionList | ExprPairList ) [ "," ] ] ")" . |
| 1730 | LiteralType = Type | "[" "..." "]" ElementType . |
| 1731 | ExprPairList = ExprPair { "," ExprPair } . |
| 1732 | ExprPair = Expression ":" Expression . |
| 1733 | </pre> |
Robert Griesemer | 0976e34 | 2008-09-03 13:37:44 -0700 | [diff] [blame] | 1734 | |
Robert Griesemer | 91bbd64 | 2009-01-07 09:31:35 -0800 | [diff] [blame] | 1735 | The LiteralType must be an struct, array, slice, or map type. |
| 1736 | The types of the expressions must match the respective field, element, and |
| 1737 | key types of the LiteralType; there is no automatic type conversion. |
Robert Griesemer | 4712165 | 2008-10-23 17:19:56 -0700 | [diff] [blame] | 1738 | Composite literals are values of the type specified by LiteralType; that is |
| 1739 | a new value is created every time the literal is evaluated. To get |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1740 | a pointer to the literal, the address operator "&" must be used. |
| 1741 | <p> |
Robert Griesemer | 0976e34 | 2008-09-03 13:37:44 -0700 | [diff] [blame] | 1742 | Given |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1743 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1744 | <pre> |
| 1745 | type Rat struct { num, den int } |
| 1746 | type Num struct { r Rat; f float; s string } |
| 1747 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1748 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1749 | one can write |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1750 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1751 | <pre> |
| 1752 | pi := Num(Rat(22, 7), 3.14159, "pi"); |
| 1753 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1754 | |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 1755 | The length of an array literal is the length specified in the LiteralType. |
| 1756 | If fewer elements than the length are provided in the literal, the missing |
| 1757 | elements are set to the appropriate zero value for the array element type. |
Robert Griesemer | 91bbd64 | 2009-01-07 09:31:35 -0800 | [diff] [blame] | 1758 | It is an error to provide more elements than specified in LiteralType. The |
| 1759 | notation "..." may be used in place of the length expression to denote a |
| 1760 | length equal to the number of elements in the literal. |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 1761 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1762 | <pre> |
| 1763 | buffer := [10]string(); // len(buffer) == 10 |
| 1764 | primes := [6]int(2, 3, 5, 7, 9, 11); // len(primes) == 6 |
| 1765 | days := [...]string("sat", "sun"); // len(days) == 2 |
| 1766 | </pre> |
Robert Griesemer | 91bbd64 | 2009-01-07 09:31:35 -0800 | [diff] [blame] | 1767 | |
| 1768 | A slice literal is a slice describing the entire underlying array literal. |
| 1769 | Thus, the length and capacity of a slice literal is the number of elements |
| 1770 | provided in the literal. A slice literal of the form |
| 1771 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1772 | <pre> |
| 1773 | []T(x1, x2, ... xn) |
| 1774 | </pre> |
Robert Griesemer | 91bbd64 | 2009-01-07 09:31:35 -0800 | [diff] [blame] | 1775 | |
| 1776 | is essentially a shortcut for a slice operation applied to an array literal: |
| 1777 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1778 | <pre> |
| 1779 | [n]T(x1, x2, ... xn)[0 : n] |
| 1780 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1781 | |
| 1782 | Map literals are similar except the elements of the expression list are |
| 1783 | key-value pairs separated by a colon: |
| 1784 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1785 | <pre> |
| 1786 | m := map[string]int("good": 0, "bad": 1, "indifferent": 7); |
| 1787 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1788 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1789 | <font color=red> |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 1790 | TODO: Consider adding helper syntax for nested composites |
| 1791 | (avoids repeating types but complicates the spec needlessly.) |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1792 | </font> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1793 | |
| 1794 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1795 | <h3>Function literals</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1796 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1797 | A function literal represents an anonymous function. It consists of a |
| 1798 | specification of the function type and the function body. The parameter |
| 1799 | and result types of the function type must all be complete types (§Types). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1800 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1801 | <pre> |
| 1802 | FunctionLit = "func" Signature Block . |
| 1803 | Block = "{" [ StatementList ] "}" . |
| 1804 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1805 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 1806 | The type of a function literal is the function type specified. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1807 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1808 | <pre> |
| 1809 | func (a, b int, z float) bool { return a*b < int(z); } |
| 1810 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1811 | |
Robert Griesemer | 7231ceb | 2008-09-08 15:01:04 -0700 | [diff] [blame] | 1812 | A function literal can be assigned to a variable of the |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 1813 | corresponding function type, or invoked directly. |
Robert Griesemer | 7231ceb | 2008-09-08 15:01:04 -0700 | [diff] [blame] | 1814 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1815 | <pre> |
| 1816 | f := func(x, y int) int { return x + y; } |
| 1817 | func(ch chan int) { ch <- ACK; } (reply_chan) |
| 1818 | </pre> |
Robert Griesemer | 7231ceb | 2008-09-08 15:01:04 -0700 | [diff] [blame] | 1819 | |
Robert Griesemer | d8a764c | 2009-02-06 17:01:10 -0800 | [diff] [blame] | 1820 | Function literals are "closures": they may refer to variables |
| 1821 | defined in a surrounding function. Those variables are then shared between |
| 1822 | the surrounding function and the function literal, and they survive as long |
| 1823 | as they are accessible in any way. |
Robert Griesemer | 7231ceb | 2008-09-08 15:01:04 -0700 | [diff] [blame] | 1824 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1825 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1826 | <h3>Primary expressions</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1827 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1828 | <pre> |
| 1829 | PrimaryExpr = |
| 1830 | Operand | |
| 1831 | PrimaryExpr Selector | |
| 1832 | PrimaryExpr Index | |
| 1833 | PrimaryExpr Slice | |
| 1834 | PrimaryExpr TypeGuard | |
| 1835 | PrimaryExpr Call . |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 1836 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1837 | Selector = "." identifier . |
| 1838 | Index = "[" Expression "]" . |
| 1839 | Slice = "[" Expression ":" Expression "]" . |
| 1840 | TypeGuard = "." "(" Type ")" . |
| 1841 | Call = "(" [ ExpressionList ] ")" . |
| 1842 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1843 | |
| 1844 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1845 | <pre> |
| 1846 | x |
| 1847 | 2 |
| 1848 | (s + ".txt") |
| 1849 | f(3.1415, true) |
| 1850 | Point(1, 2) |
| 1851 | m["foo"] |
| 1852 | s[i : j + 1] |
| 1853 | obj.color |
| 1854 | Math.sin |
| 1855 | f.p[i].x() |
| 1856 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1857 | |
| 1858 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1859 | <h3>Selectors</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1860 | |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1861 | A primary expression of the form |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1862 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1863 | <pre> |
| 1864 | x.f |
| 1865 | </pre> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1866 | |
| 1867 | denotes the field or method f of the value denoted by x (or of *x if |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1868 | x is of pointer type). The identifier f is called the (field or method) |
| 1869 | ``selector''. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1870 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1871 | A selector f may denote a field f declared in a type T, or it may refer |
| 1872 | to a field f declared in a nested anonymous field of T. Analogously, |
| 1873 | f may denote a method f of T, or it may refer to a method f of the type |
| 1874 | of a nested anonymous field of T. The number of anonymous fields traversed |
| 1875 | to get to the field or method is called its ``depth'' in T. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1876 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1877 | More precisely, the depth of a field or method f declared in T is zero. |
| 1878 | The depth of a field or method f declared anywhere inside |
| 1879 | an anonymous field A declared in T is the depth of f in A plus one. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1880 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1881 | The following rules apply to selectors: |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1882 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1883 | 1) For a value x of type T or *T where T is not an interface type, |
| 1884 | x.f denotes the field or method at the shallowest depth in T where there |
| 1885 | is such an f. The type of x.f is the type of the field or method f. |
| 1886 | If there is not exactly one f with shallowest depth, the selector |
| 1887 | expression is illegal. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1888 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1889 | 2) For a variable x of type I or *I where I is an interface type, |
| 1890 | x.f denotes the actual method with name f of the value assigned |
| 1891 | to x if there is such a method. The type of x.f is the type |
| 1892 | of the method f. If no value or nil was assigned to x, x.f is illegal. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1893 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1894 | 3) In all other cases, x.f is illegal. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1895 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1896 | Thus, selectors automatically dereference pointers as necessary. For instance, |
| 1897 | for an x of type *T where T declares an f, x.f is a shortcut for (*x).f. |
| 1898 | Furthermore, for an x of type T containing an anonymous field A declared as *A |
| 1899 | inside T, and where A contains a field f, x.f is a shortcut for (*x.A).f |
| 1900 | (assuming that the selector is legal in the first place). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1901 | <p> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1902 | The following examples illustrate selector use in more detail. Given the |
| 1903 | declarations: |
| 1904 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1905 | <pre> |
| 1906 | type T0 struct { |
| 1907 | x int; |
| 1908 | } |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1909 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1910 | func (recv *T0) M0() |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1911 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1912 | type T1 struct { |
| 1913 | y int; |
| 1914 | } |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1915 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1916 | func (recv T1) M1() |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1917 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1918 | type T2 struct { |
| 1919 | z int; |
| 1920 | T1; |
| 1921 | *T0; |
| 1922 | } |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1923 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1924 | func (recv *T2) M2() |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1925 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1926 | var p *T2; // with p != nil and p.T1 != nil |
| 1927 | </pre> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1928 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 1929 | one can write: |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1930 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1931 | <pre> |
| 1932 | p.z // (*p).z |
| 1933 | p.y // ((*p).T1).y |
| 1934 | p.x // (*(*p).T0).x |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1935 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1936 | p.M2 // (*p).M2 |
| 1937 | p.M1 // ((*p).T1).M1 |
| 1938 | p.M0 // ((*p).T0).M0 |
| 1939 | </pre> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1940 | |
| 1941 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1942 | <font color=red> |
Robert Griesemer | 071c91b | 2008-10-23 12:04:45 -0700 | [diff] [blame] | 1943 | TODO: Specify what happens to receivers. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1944 | </font> |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1945 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1946 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1947 | <h3>Indexes</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1948 | |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1949 | A primary expression of the form |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1950 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1951 | <pre> |
| 1952 | a[x] |
| 1953 | </pre> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1954 | |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1955 | <p> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1956 | denotes the array or map element x. The value x is called the |
| 1957 | ``array index'' or ``map key'', respectively. The following |
| 1958 | rules apply: |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1959 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1960 | <p> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1961 | For a of type A or *A where A is an array type (§Array types): |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1962 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1963 | <ul> |
| 1964 | <li>x must be an integer value and 0 <= x < len(a) |
| 1965 | <li>a[x] is the array element at index x and the type of a[x] |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1966 | is the element type of A |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1967 | </ul> |
| 1968 | <p> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1969 | For a of type *M, where M is a map type (§Map types): |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 1970 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1971 | <ul> |
| 1972 | <li>x must be of the same type as the key type of M |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1973 | and the map must contain an entry with key x |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1974 | <li>a[x] is the map value with key x and the type of a[x] |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1975 | is the value type of M |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1976 | </ul> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1977 | |
| 1978 | Otherwise a[x] is illegal. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1979 | <p> |
| 1980 | <font color=red> |
Robert Griesemer | bbfe312 | 2008-10-09 17:12:09 -0700 | [diff] [blame] | 1981 | TODO: Need to expand map rules for assignments of the form v, ok = m[k]. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1982 | </font> |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 1983 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1984 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1985 | <h3>Slices</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1986 | |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 1987 | Strings, arrays, and slices can be ``sliced'' to construct substrings or descriptors |
| 1988 | of subarrays. The index expressions in the slice select which elements appear |
| 1989 | in the result. The result has indexes starting at 0 and length equal to the |
| 1990 | difference in the index values in the slice. After slicing the array "a" |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1991 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1992 | <pre> |
| 1993 | a := [4]int(1, 2, 3, 4); |
| 1994 | s := a[1:3]; |
| 1995 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1996 | |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 1997 | the slice "s" has type "[]int", length 2, and elements |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 1998 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 1999 | <pre> |
| 2000 | s[0] == 2 |
| 2001 | s[1] == 3 |
| 2002 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2003 | |
| 2004 | The index values in the slice must be in bounds for the original |
| 2005 | array (or string) and the slice length must be non-negative. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2006 | <p> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 2007 | If the sliced operand is a string, the result of the slice operation is another |
| 2008 | string (§String types). If the sliced operand is an array or slice, the result |
| 2009 | of the slice operation is a slice (§Slice types). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2010 | |
| 2011 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2012 | <h3>Type guards</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2013 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2014 | For an expression "x" and a type "T", the primary expression |
| 2015 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2016 | <pre> |
| 2017 | x.(T) |
| 2018 | </pre> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2019 | |
| 2020 | asserts that the value stored in "x" is an element of type "T" (§Types). |
| 2021 | The notation ".(T)" is called a ``type guard'', and "x.(T)" is called |
| 2022 | a ``guarded expression''. The type of "x" must be an interface type. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2023 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2024 | More precisely, if "T" is not an interface type, the expression asserts |
| 2025 | that the dynamic type of "x" is identical to the type "T" (§Types). |
| 2026 | If "T" is an interface type, the expression asserts that the dynamic type |
| 2027 | of T implements the interface "T" (§Interface types). Because it can be |
| 2028 | verified statically, a type guard in which the static type of "x" implements |
| 2029 | the interface "T" is illegal. The type guard is said to succeed if the |
| 2030 | assertion holds. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2031 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2032 | If the type guard succeeds, the value of the guarded expression is the value |
| 2033 | stored in "x" and its type is "T". If the type guard fails, a run-time |
| 2034 | exception occurs. In other words, even though the dynamic type of "x" |
| 2035 | is only known at run-time, the type of the guarded expression "x.(T)" is |
| 2036 | known to be "T" in a correct program. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2037 | <p> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2038 | As a special form, if a guarded expression is used in an assignment |
| 2039 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2040 | <pre> |
| 2041 | v, ok = x.(T) |
| 2042 | v, ok := x.(T) |
| 2043 | </pre> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2044 | |
| 2045 | the result of the guarded expression is a pair of values with types "(T, bool)". |
| 2046 | If the type guard succeeds, the expression returns the pair "(x.(T), true)"; |
| 2047 | that is, the value stored in "x" (of type "T") is assigned to "v", and "ok" |
| 2048 | is set to true. If the type guard fails, the value in "v" is set to the initial |
| 2049 | value for the type of "v" (§Program initialization and execution), and "ok" is |
| 2050 | set to false. No run-time exception occurs in this case. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2051 | <p> |
| 2052 | <font color=red> |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2053 | TODO add examples |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2054 | </font> |
Robert Griesemer | 7a4ed4f | 2008-09-03 15:15:51 -0700 | [diff] [blame] | 2055 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2056 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2057 | <h3>Calls</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2058 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2059 | <font color=red> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2060 | TODO: This needs to be expanded and cleaned up. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2061 | </font> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2062 | |
| 2063 | Given a function or a function variable p, one writes |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2064 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2065 | <pre> |
| 2066 | p() |
| 2067 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2068 | |
| 2069 | to call the function. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2070 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2071 | A method is called using the notation |
| 2072 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2073 | <pre> |
| 2074 | receiver.method() |
| 2075 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2076 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2077 | where receiver is a value of the receiver type of the method. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2078 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2079 | For instance, given a *Point variable pt, one may call |
| 2080 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2081 | <pre> |
| 2082 | pt.Scale(3.5) |
| 2083 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2084 | |
| 2085 | The type of a method is the type of a function with the receiver as first |
| 2086 | argument. For instance, the method "Scale" has type |
| 2087 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2088 | <pre> |
| 2089 | (p *Point, factor float) |
| 2090 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2091 | |
| 2092 | However, a function declared this way is not a method. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2093 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2094 | There is no distinct method type and there are no method literals. |
| 2095 | |
| 2096 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2097 | <h3>Parameter passing</h3> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2098 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2099 | <font color=red> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2100 | TODO expand this section (right now only "..." parameters are covered). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2101 | </font> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2102 | |
| 2103 | Inside a function, the type of the "..." parameter is the empty interface |
| 2104 | "interface {}". The dynamic type of the parameter - that is, the type of |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2105 | the value stored in the parameter - is of the form (in pseudo- |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2106 | notation) |
| 2107 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2108 | <pre> |
| 2109 | *struct { |
| 2110 | arg(0) typeof(arg(0)); |
| 2111 | arg(1) typeof(arg(1)); |
| 2112 | arg(2) typeof(arg(2)); |
| 2113 | ... |
| 2114 | arg(n-1) typeof(arg(n-1)); |
| 2115 | } |
| 2116 | </pre> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2117 | |
| 2118 | where the "arg(i)"'s correspond to the actual arguments passed in place |
| 2119 | of the "..." parameter (the parameter and type names are for illustration |
| 2120 | only). Reflection code may be used to access the struct value and its fields. |
| 2121 | Thus, arguments provided in place of a "..." parameter are wrapped into |
| 2122 | a corresponding struct, and a pointer to the struct is passed to the |
| 2123 | function instead of the actual arguments. |
| 2124 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2125 | For instance, consider the function |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2126 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2127 | <pre> |
| 2128 | func f(x int, s string, f_extra ...) |
| 2129 | </pre> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2130 | |
| 2131 | and the call |
| 2132 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2133 | <pre> |
| 2134 | f(42, "foo", 3.14, true, []int(1, 2, 3)) |
| 2135 | </pre> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2136 | |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 2137 | Upon invocation, the parameters "3.14", "true", and "[]int(1, 2, 3)" |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2138 | are wrapped into a struct and the pointer to the struct is passed to f. |
| 2139 | In f the type of parameter "f_extra" is "interface{}". |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2140 | The dynamic type of "f_extra" is the type of the value assigned |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2141 | to it upon invocation (the field names "arg0", "arg1", "arg2" are made |
| 2142 | up for illustration only, they are not accessible via reflection): |
| 2143 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2144 | <pre> |
| 2145 | *struct { |
| 2146 | arg0 float; |
| 2147 | arg1 bool; |
| 2148 | arg2 []int; |
| 2149 | } |
| 2150 | </pre> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2151 | |
| 2152 | The values of the fields "arg0", "arg1", and "arg2" are "3.14", "true", |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 2153 | and "[]int(1, 2, 3)". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2154 | <p> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2155 | As a special case, if a function passes a "..." parameter as the argument |
| 2156 | for a "..." parameter of a function, the parameter is not wrapped again into |
| 2157 | a struct. Instead it is passed along unchanged. For instance, the function |
| 2158 | f may call a function g with declaration |
| 2159 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2160 | <pre> |
| 2161 | func g(x int, g_extra ...) |
| 2162 | </pre> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2163 | |
| 2164 | as |
| 2165 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2166 | <pre> |
| 2167 | g(x, f_extra); |
| 2168 | </pre> |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2169 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 2170 | Inside g, the value stored in g_extra is the same as the value stored |
Robert Griesemer | 69e26bf | 2008-11-04 16:46:45 -0800 | [diff] [blame] | 2171 | in f_extra. |
| 2172 | |
| 2173 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2174 | <h3>Operators</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2175 | |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2176 | Operators combine operands into expressions. |
| 2177 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2178 | <pre> |
| 2179 | Expression = UnaryExpr | Expression binaryOp UnaryExpr . |
| 2180 | UnaryExpr = PrimaryExpr | unary_op UnaryExpr . |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 2181 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2182 | binary_op = log_op | com_op | rel_op | add_op | mul_op . |
| 2183 | log_op = "||" | "&&" . |
| 2184 | com_op = "<-" . |
| 2185 | rel_op = "==" | "!=" | "<" | "<=" | ">" | ">=" . |
| 2186 | add_op = "+" | "-" | "|" | "^" . |
| 2187 | mul_op = "*" | "/" | "%" | "<<" | ">>" | "&" . |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2188 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2189 | unary_op = "+" | "-" | "!" | "^" | "*" | "&" | "<-" . |
| 2190 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2191 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2192 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 2193 | The operand types in binary operations must be equal, with the following exceptions: |
| 2194 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2195 | <ul> |
| 2196 | <li>If one operand has numeric type and the other operand is |
Robert Griesemer | a6b546f | 2008-10-20 11:46:40 -0700 | [diff] [blame] | 2197 | an ideal number, the ideal number is converted to match the type of |
| 2198 | the other operand (§Expression). |
Robert Griesemer | c8e1876 | 2008-09-12 12:26:22 -0700 | [diff] [blame] | 2199 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2200 | <li>If both operands are ideal numbers, the conversion is to ideal floats |
Robert Griesemer | e28cceb | 2008-09-11 18:23:28 -0700 | [diff] [blame] | 2201 | if one of the operands is an ideal float (relevant for "/" and "%"). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2202 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2203 | <li>The right operand in a shift operation must be always be an unsigned int |
Robert Griesemer | a6b546f | 2008-10-20 11:46:40 -0700 | [diff] [blame] | 2204 | (or an ideal number that can be safely converted into an unsigned int) |
| 2205 | (§Arithmetic operators). |
| 2206 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2207 | <li>When comparing two operands of channel type, the channel value types |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 2208 | must be equal but the channel direction is ignored. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2209 | </ul> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 2210 | |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 2211 | Unary operators have the highest precedence. They are evaluated from |
Robert Griesemer | a6b546f | 2008-10-20 11:46:40 -0700 | [diff] [blame] | 2212 | right to left. Note that "++" and "--" are outside the unary operator |
| 2213 | hierachy (they are statements) and they apply to the operand on the left. |
| 2214 | Specifically, "*p++" means "(*p)++" in Go (as opposed to "*(p++)" in C). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2215 | <p> |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2216 | There are six precedence levels for binary operators: |
| 2217 | multiplication operators bind strongest, followed by addition |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 2218 | operators, comparison operators, communication operators, |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2219 | "&&" (logical and), and finally "||" (logical or) with the |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 2220 | lowest precedence: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2221 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2222 | <pre> |
| 2223 | Precedence Operator |
| 2224 | 6 * / % << >> & |
| 2225 | 5 + - | ^ |
| 2226 | 4 == != < <= > >= |
| 2227 | 3 <- |
| 2228 | 2 && |
| 2229 | 1 || |
| 2230 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2231 | |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 2232 | Binary operators of the same precedence associate from left to right. |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2233 | For instance, "x / y / z" stands for "(x / y) / z". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2234 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2235 | Examples |
| 2236 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2237 | <pre> |
| 2238 | +x |
| 2239 | 23 + 3*x[i] |
| 2240 | x <= f() |
| 2241 | ^a >> b |
| 2242 | f() || g() |
| 2243 | x == y + 1 && <-chan_ptr > 0 |
| 2244 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2245 | |
| 2246 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2247 | <h3>Arithmetic operators</h3> |
| 2248 | <p> |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2249 | Arithmetic operators apply to numeric types and yield a result of the same |
| 2250 | type as the first operand. The four standard arithmetic operators ("+", "-", |
| 2251 | "*", "/") apply to both integer and floating point types, while "+" also applies |
| 2252 | to strings and arrays; all other arithmetic operators apply to integer types only. |
| 2253 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2254 | <pre> |
| 2255 | + sum integers, floats, strings, arrays |
| 2256 | - difference integers, floats |
| 2257 | * product integers, floats |
| 2258 | / quotient integers, floats |
| 2259 | % remainder integers |
| 2260 | |
| 2261 | & bitwise and integers |
| 2262 | | bitwise or integers |
| 2263 | ^ bitwise xor integers |
| 2264 | |
| 2265 | << left shift integer << unsigned integer |
| 2266 | >> right shift integer >> unsigned integer |
| 2267 | </pre> |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2268 | |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 2269 | Strings can be concatenated using the "+" operator (or the "+=" assignment): |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2270 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2271 | <pre> |
| 2272 | s := "hi" + string(c) |
| 2273 | </pre> |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2274 | |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 2275 | String addition creates a new string by copying the elements. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2276 | <p> |
Robert Griesemer | 7231ceb | 2008-09-08 15:01:04 -0700 | [diff] [blame] | 2277 | For integer values, "/" and "%" satisfy the following relationship: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2278 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2279 | <pre> |
| 2280 | (a / b) * b + a % b == a |
| 2281 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2282 | |
| 2283 | and |
| 2284 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2285 | <pre> |
| 2286 | (a / b) is "truncated towards zero". |
| 2287 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2288 | |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2289 | Examples: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2290 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2291 | <pre> |
| 2292 | x y x / y x % y |
| 2293 | 5 3 1 2 |
| 2294 | -5 3 -1 -2 |
| 2295 | 5 -3 -1 2 |
| 2296 | -5 -3 1 -2 |
| 2297 | </pre> |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2298 | |
| 2299 | Note that if the dividend is positive and the divisor is a constant power of 2, |
| 2300 | the division may be replaced by a left shift, and computing the remainder may |
| 2301 | be replaced by a bitwise "and" operation: |
| 2302 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2303 | <pre> |
| 2304 | x x / 4 x % 4 x >> 2 x & 3 |
| 2305 | 11 2 3 2 3 |
| 2306 | -11 -2 -3 -3 1 |
| 2307 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2308 | |
| 2309 | The shift operators shift the left operand by the shift count specified by the |
| 2310 | right operand. They implement arithmetic shifts if the left operand is a signed |
| 2311 | integer, and logical shifts if it is an unsigned integer. The shift count must |
| 2312 | be an unsigned integer. There is no upper limit on the shift count. It is |
| 2313 | as if the left operand is shifted "n" times by 1 for a shift count of "n". |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 2314 | Specifically, "x << 1" is the same as "x*2"; and "x >> 1" is the same as |
| 2315 | "x/2 truncated towards negative infinity". |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2316 | |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 2317 | For integer operands, the unary operators "+", "-", and "^" are defined as |
| 2318 | follows: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2319 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2320 | <pre> |
| 2321 | +x is 0 + x |
| 2322 | -x negation is 0 - x |
| 2323 | ^x bitwise complement is m ^ x with m = "all bits set to 1" |
| 2324 | </pre> |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 2325 | |
| 2326 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2327 | <h3>Integer overflow</h3> |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 2328 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2329 | For unsigned integer values, the operations "+", "-", "*", and "<<" are |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 2330 | computed modulo 2^n, where n is the bit width of the unsigned integer type |
| 2331 | (§Arithmetic types). Loosely speaking, these unsigned integer operations |
| 2332 | discard high bits upon overflow, and programs may rely on ``wrap around''. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2333 | <p> |
| 2334 | For signed integers, the operations "+", "-", "*", and "<<" may legally |
Robert Griesemer | 9dfb2ea | 2008-12-12 10:30:10 -0800 | [diff] [blame] | 2335 | overflow and the resulting value exists and is deterministically defined |
| 2336 | by the signed integer representation, the operation, and its operands. |
| 2337 | No exception is raised as a result of overflow. As a consequence, a |
| 2338 | compiler may not optimize code under the assumption that overflow does |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2339 | not occur. For instance, it may not assume that "x < x + 1" is always true. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2340 | |
| 2341 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2342 | <h3>Comparison operators</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2343 | |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2344 | Comparison operators yield a boolean result. All comparison operators apply |
| 2345 | to strings and numeric types. The operators "==" and "!=" also apply to |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 2346 | boolean values, pointer, interface, and channel types. Slice and |
| 2347 | map types only support testing for equality against the predeclared value |
| 2348 | "nil". |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2349 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2350 | <pre> |
| 2351 | == equal |
| 2352 | != not equal |
| 2353 | < less |
| 2354 | <= less or equal |
| 2355 | > greater |
| 2356 | >= greater or equal |
| 2357 | </pre> |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2358 | |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 2359 | Strings are compared byte-wise (lexically). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2360 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 2361 | Booleans are equal if they are either both "true" or both "false". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2362 | <p> |
Robert Griesemer | b5e0cc7 | 2008-10-10 16:34:44 -0700 | [diff] [blame] | 2363 | Pointers are equal if they point to the same value. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2364 | <p> |
Robert Griesemer | 18b05c1 | 2009-01-26 09:34:19 -0800 | [diff] [blame] | 2365 | Interface, slice, map, and channel types can be compared for equality according |
| 2366 | to the rules specified in the section on §Interface types, §Slice types, §Map types, |
| 2367 | and §Channel types, respectively. |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 2368 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2369 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2370 | <h3>Logical operators</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2371 | |
Robert Griesemer | 41d65ac | 2008-09-04 15:17:27 -0700 | [diff] [blame] | 2372 | Logical operators apply to boolean operands and yield a boolean result. |
| 2373 | The right operand is evaluated conditionally. |
| 2374 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2375 | <pre> |
| 2376 | && conditional and p && q is "if p then q else false" |
| 2377 | || conditional or p || q is "if p then true else q" |
| 2378 | ! not !p is "not p" |
| 2379 | </pre> |
Robert Griesemer | 7a4ed4f | 2008-09-03 15:15:51 -0700 | [diff] [blame] | 2380 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2381 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2382 | <h3>Address operators</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2383 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2384 | <font color=red>TODO: Need to talk about unary "*", clean up section below.</font> |
| 2385 | <p> |
| 2386 | <font color=red>TODO: This text needs to be cleaned up and go elsewhere, there are no address |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2387 | operators involved. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2388 | </font> |
| 2389 | <p> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2390 | Methods are a form of function, and a method ``value'' has a function type. |
| 2391 | Consider the type T with method M: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2392 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2393 | <pre> |
| 2394 | type T struct { |
| 2395 | a int; |
| 2396 | } |
| 2397 | func (tp *T) M(a int) int; |
| 2398 | var t *T; |
| 2399 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2400 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2401 | To construct the value of method M, one writes |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2402 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2403 | <pre> |
| 2404 | t.M |
| 2405 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2406 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2407 | using the variable t (not the type T). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2408 | <font color=red>TODO: It makes perfect sense to be able to say T.M (in fact, it makes more |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2409 | sense then t.M, since only the type T is needed to find the method M, i.e., |
| 2410 | its address). TBD. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2411 | </font> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2412 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2413 | The expression t.M is a function value with type |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2414 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2415 | <pre> |
| 2416 | func (t *T, a int) int |
| 2417 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2418 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2419 | and may be invoked only as a function, not as a method: |
| 2420 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2421 | <pre> |
| 2422 | var f func (t *T, a int) int; |
| 2423 | f = t.M; |
| 2424 | x := f(t, 7); |
| 2425 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2426 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2427 | Note that one does not write t.f(7); taking the value of a method demotes |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2428 | it to a function. |
| 2429 | |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2430 | In general, given type T with method M and variable t of type T, |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2431 | the method invocation |
| 2432 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2433 | <pre> |
| 2434 | t.M(args) |
| 2435 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2436 | |
| 2437 | is equivalent to the function call |
| 2438 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2439 | <pre> |
| 2440 | (t.M)(t, args) |
| 2441 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2442 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2443 | <font color=red> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2444 | TODO: should probably describe the effect of (t.m) under §Expressions if t.m |
| 2445 | denotes a method: Effect is as described above, converts into function. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2446 | </font> |
| 2447 | <p> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2448 | If T is an interface type, the expression t.M does not determine which |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2449 | underlying type's M is called until the point of the call itself. Thus given |
Robert Griesemer | d8a764c | 2009-02-06 17:01:10 -0800 | [diff] [blame] | 2450 | T1 and T2, both implementing interface I with method M, the sequence |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2451 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2452 | <pre> |
| 2453 | var t1 *T1; |
| 2454 | var t2 *T2; |
| 2455 | var i I = t1; |
| 2456 | m := i.M; |
| 2457 | m(t2, 7); |
| 2458 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2459 | |
| 2460 | will invoke t2.M() even though m was constructed with an expression involving |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2461 | t1. Effectively, the value of m is a function literal |
| 2462 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2463 | <pre> |
| 2464 | func (recv I, a int) { |
| 2465 | recv.M(a); |
| 2466 | } |
| 2467 | </pre> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2468 | |
| 2469 | that is automatically created. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2470 | <p> |
| 2471 | <font color=red> |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2472 | TODO: Document implementation restriction: It is illegal to take the address |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2473 | of a result parameter (e.g.: func f() (x int, p *int) { return 2, &x }). |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2474 | (TBD: is it an implementation restriction or fact?) |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2475 | </font> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2476 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2477 | <h3>Communication operators</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2478 | |
| 2479 | The syntax presented above covers communication operations. This |
| 2480 | section describes their form and function. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2481 | <p> |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 2482 | Here the term "channel" means "variable of type chan". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2483 | <p> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 2484 | The built-in function "make" makes a new channel value: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2485 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2486 | <pre> |
| 2487 | ch := make(chan int) |
| 2488 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2489 | |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 2490 | An optional argument to "make()" specifies a buffer size for an |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2491 | asynchronous channel; if absent or zero, the channel is synchronous: |
| 2492 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2493 | <pre> |
| 2494 | sync_chan := make(chan int) |
| 2495 | buffered_chan := make(chan int, 10) |
| 2496 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2497 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2498 | The send operation uses the binary operator "<-", which operates on |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2499 | a channel and a value (expression): |
| 2500 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2501 | <pre> |
| 2502 | ch <- 3 |
| 2503 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2504 | |
| 2505 | In this form, the send operation is an (expression) statement that |
Rob Pike | 569a107 | 2008-10-03 11:18:45 -0700 | [diff] [blame] | 2506 | sends the value on the channel. Both the channel and the expression |
| 2507 | are evaluated before communication begins. Communication blocks |
| 2508 | until the send can proceed, at which point the value is transmitted |
| 2509 | on the channel. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2510 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2511 | If the send operation appears in an expression context, the value |
| 2512 | of the expression is a boolean and the operation is non-blocking. |
| 2513 | The value of the boolean reports true if the communication succeeded, |
| 2514 | false if it did not. These two examples are equivalent: |
| 2515 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2516 | <pre> |
| 2517 | ok := ch <- 3; |
| 2518 | if ok { print("sent") } else { print("not sent") } |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2519 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2520 | if ch <- 3 { print("sent") } else { print("not sent") } |
| 2521 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2522 | |
| 2523 | In other words, if the program tests the value of a send operation, |
| 2524 | the send is non-blocking and the value of the expression is the |
| 2525 | success of the operation. If the program does not test the value, |
| 2526 | the operation blocks until it succeeds. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2527 | <p> |
| 2528 | <font color=red> |
Robert Griesemer | 2902a82 | 2008-09-17 13:57:11 -0700 | [diff] [blame] | 2529 | TODO: Adjust the above depending on how we rule on the ok semantics. |
Rob Pike | 569a107 | 2008-10-03 11:18:45 -0700 | [diff] [blame] | 2530 | For instance, does the sent expression get evaluated if ok is false? |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2531 | </font> |
| 2532 | <p> |
| 2533 | The receive operation uses the prefix unary operator "<-". |
Robert Griesemer | 2902a82 | 2008-09-17 13:57:11 -0700 | [diff] [blame] | 2534 | The value of the expression is the value received: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2535 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2536 | <pre> |
| 2537 | <-ch |
| 2538 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2539 | |
| 2540 | The expression blocks until a value is available, which then can |
| 2541 | be assigned to a variable or used like any other expression: |
| 2542 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2543 | <pre> |
| 2544 | v1 := <-ch |
| 2545 | v2 = <-ch |
| 2546 | f(<-ch) |
| 2547 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2548 | |
| 2549 | If the receive expression does not save the value, the value is |
| 2550 | discarded: |
| 2551 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2552 | <pre> |
| 2553 | <-strobe // wait until clock pulse |
| 2554 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2555 | |
Robert Griesemer | 2902a82 | 2008-09-17 13:57:11 -0700 | [diff] [blame] | 2556 | If a receive expression is used in a tuple assignment of the form |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2557 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2558 | <pre> |
| 2559 | x, ok = <-ch; // or: x, ok := <-ch |
| 2560 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2561 | |
Robert Griesemer | 2902a82 | 2008-09-17 13:57:11 -0700 | [diff] [blame] | 2562 | the receive operation becomes non-blocking, and the boolean variable |
| 2563 | "ok" will be set to "true" if the receive operation succeeded, and set |
| 2564 | to "false" otherwise. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2565 | |
| 2566 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2567 | <h3>Constant expressions</h3> |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 2568 | |
| 2569 | A constant expression is an expression whose operands are all constants |
| 2570 | (§Constants). Additionally, the result of the predeclared functions |
| 2571 | below (with appropriate arguments) is also constant: |
| 2572 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2573 | <pre> |
| 2574 | len(a) if a is an array (as opposed to an array slice) |
| 2575 | </pre> |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 2576 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2577 | <font color=red> |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 2578 | TODO: Complete this list as needed. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2579 | </font> |
| 2580 | <p> |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 2581 | Constant expressions can be evaluated at compile time. |
| 2582 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2583 | <hr> |
Robert Griesemer | b90b213 | 2008-09-19 15:49:55 -0700 | [diff] [blame] | 2584 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2585 | <h2>Statements</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2586 | |
| 2587 | Statements control execution. |
| 2588 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2589 | <pre> |
| 2590 | Statement = |
| 2591 | Declaration | LabelDecl | EmptyStat | |
| 2592 | SimpleStat | GoStat | ReturnStat | BreakStat | ContinueStat | GotoStat | |
| 2593 | FallthroughStat | Block | IfStat | SwitchStat | SelectStat | ForStat | |
| 2594 | DeferStat . |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 2595 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2596 | SimpleStat = |
| 2597 | ExpressionStat | IncDecStat | Assignment | SimpleVarDecl . |
| 2598 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2599 | |
Robert Griesemer | 7271e04 | 2008-10-09 20:05:24 -0700 | [diff] [blame] | 2600 | |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 2601 | Statements in a statement list are separated by semicolons, which can be |
| 2602 | omitted in some cases as expressed by the OptSemicolon production. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2603 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2604 | <pre> |
| 2605 | StatementList = Statement { OptSemicolon Statement } . |
| 2606 | </pre> |
Robert Griesemer | 7271e04 | 2008-10-09 20:05:24 -0700 | [diff] [blame] | 2607 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2608 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 2609 | A semicolon may be omitted immediately following: |
| 2610 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2611 | <ul> |
| 2612 | <li>a closing parenthesis ")" ending a list of declarations (§Declarations and scope rules) |
| 2613 | <li>a closing brace "}" ending a type declaration (§Type declarations) |
| 2614 | <li>a closing brace "}" ending a block (including switch and select statements) |
| 2615 | <li>a label declaration (§Label declarations) |
| 2616 | </ul> |
Robert Griesemer | 7271e04 | 2008-10-09 20:05:24 -0700 | [diff] [blame] | 2617 | |
| 2618 | In all other cases a semicolon is required to separate two statements. Since there |
| 2619 | is an empty statement, a statement list can always be ``terminated'' with a semicolon. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2620 | |
| 2621 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2622 | <h3>Empty statements</h3> |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 2623 | |
| 2624 | The empty statement does nothing. |
| 2625 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2626 | <pre> |
| 2627 | EmptyStat = . |
| 2628 | </pre> |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 2629 | |
| 2630 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2631 | <h3>Expression statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2632 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2633 | <pre> |
| 2634 | ExpressionStat = Expression . |
| 2635 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2636 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2637 | <pre> |
| 2638 | f(x+y) |
| 2639 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2640 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2641 | <font color=red> |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 2642 | TODO: specify restrictions. 6g only appears to allow calls here. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2643 | </font> |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 2644 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2645 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2646 | <h3>IncDec statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2647 | |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 2648 | The "++" and "--" statements increment or decrement their operands |
| 2649 | by the (ideal) constant value 1. |
| 2650 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2651 | <pre> |
| 2652 | IncDecStat = Expression ( "++" | "--" ) . |
| 2653 | </pre> |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 2654 | |
| 2655 | The following assignment statements (§Assignments) are semantically |
| 2656 | equivalent: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2657 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2658 | <pre> |
| 2659 | IncDec statement Assignment |
| 2660 | x++ x += 1 |
| 2661 | x-- x -= 1 |
| 2662 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2663 | |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 2664 | Both operators apply to integer and floating point types only. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2665 | <p> |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 2666 | Note that increment and decrement are statements, not expressions. |
| 2667 | For instance, "x++" cannot be used as an operand in an expression. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2668 | |
| 2669 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2670 | <h3>Assignments</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2671 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2672 | <pre> |
| 2673 | Assignment = ExpressionList assign_op ExpressionList . |
| 2674 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2675 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2676 | <pre> |
| 2677 | assign_op = [ add_op | mul_op ] "=" . |
| 2678 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2679 | |
| 2680 | The left-hand side must be an l-value such as a variable, pointer indirection, |
| 2681 | or an array index. |
| 2682 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2683 | <pre> |
| 2684 | x = 1 |
| 2685 | *p = f() |
| 2686 | a[i] = 23 |
| 2687 | k = <-ch |
| 2688 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2689 | |
| 2690 | As in C, arithmetic binary operators can be combined with assignments: |
| 2691 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2692 | <pre> |
| 2693 | j <<= 2 |
| 2694 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2695 | |
| 2696 | A tuple assignment assigns the individual elements of a multi-valued operation, |
| 2697 | such as function evaluation or some channel and map operations, into individual |
| 2698 | variables. For instance, a tuple assignment such as |
| 2699 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2700 | <pre> |
| 2701 | v1, v2, v3 = e1, e2, e3 |
| 2702 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2703 | |
| 2704 | assigns the expressions e1, e2, e3 to temporaries and then assigns the temporaries |
| 2705 | to the variables v1, v2, v3. Thus |
| 2706 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2707 | <pre> |
| 2708 | a, b = b, a |
| 2709 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2710 | |
| 2711 | exchanges the values of a and b. The tuple assignment |
| 2712 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2713 | <pre> |
| 2714 | x, y = f() |
| 2715 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2716 | |
| 2717 | calls the function f, which must return two values, and assigns them to x and y. |
| 2718 | As a special case, retrieving a value from a map, when written as a two-element |
| 2719 | tuple assignment, assign a value and a boolean. If the value is present in the map, |
| 2720 | the value is assigned and the second, boolean variable is set to true. Otherwise, |
| 2721 | the variable is unchanged, and the boolean value is set to false. |
| 2722 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2723 | <pre> |
| 2724 | value, present = map_var[key] |
| 2725 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2726 | |
| 2727 | To delete a value from a map, use a tuple assignment with the map on the left |
| 2728 | and a false boolean expression as the second expression on the right, such |
| 2729 | as: |
| 2730 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2731 | <pre> |
| 2732 | map_var[key] = value, false |
| 2733 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2734 | |
| 2735 | In assignments, the type of the expression must match the type of the left-hand side. |
| 2736 | |
| 2737 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2738 | <h3>If statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2739 | |
Robert Griesemer | ac05579 | 2008-09-26 11:15:14 -0700 | [diff] [blame] | 2740 | If statements specify the conditional execution of two branches; the "if" |
| 2741 | and the "else" branch. If Expression evaluates to true, |
| 2742 | the "if" branch is executed. Otherwise the "else" branch is executed if present. |
| 2743 | If Condition is omitted, it is equivalent to true. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2744 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2745 | <pre> |
| 2746 | IfStat = "if" [ [ SimpleStat ] ";" ] [ Expression ] Block [ "else" Statement ] . |
| 2747 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2748 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2749 | <pre> |
| 2750 | if x > 0 { |
| 2751 | return true; |
| 2752 | } |
| 2753 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2754 | |
| 2755 | An "if" statement may include the declaration of a single temporary variable. |
| 2756 | The scope of the declared variable extends to the end of the if statement, and |
| 2757 | the variable is initialized once before the statement is entered. |
| 2758 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2759 | <pre> |
| 2760 | if x := f(); x < y { |
| 2761 | return x; |
| 2762 | } else if x > z { |
| 2763 | return z; |
| 2764 | } else { |
| 2765 | return y; |
| 2766 | } |
| 2767 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2768 | |
| 2769 | |
Robert Griesemer | ac05579 | 2008-09-26 11:15:14 -0700 | [diff] [blame] | 2770 | <!-- |
| 2771 | TODO: gri thinks that Statement needs to be changed as follows: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2772 | |
| 2773 | IfStat = |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 2774 | "if" [ [ SimpleStat ] ";" ] [ Expression ] Block |
Robert Griesemer | ac05579 | 2008-09-26 11:15:14 -0700 | [diff] [blame] | 2775 | [ "else" ( IfStat | Block ) ] . |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2776 | |
Robert Griesemer | ac05579 | 2008-09-26 11:15:14 -0700 | [diff] [blame] | 2777 | To facilitate the "if else if" code pattern, if the "else" branch is |
| 2778 | simply another "if" statement, that "if" statement may be written |
| 2779 | without the surrounding Block: |
| 2780 | |
| 2781 | if x > 0 { |
| 2782 | return 0; |
| 2783 | } else if x > 10 { |
| 2784 | return 1; |
| 2785 | } else { |
| 2786 | return 2; |
| 2787 | } |
| 2788 | |
| 2789 | --> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2790 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2791 | <h3>Switch statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2792 | |
| 2793 | Switches provide multi-way execution. |
| 2794 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2795 | <pre> |
| 2796 | SwitchStat = "switch" [ [ SimpleStat ] ";" ] [ Expression ] "{" { CaseClause } "}" . |
| 2797 | CaseClause = SwitchCase ":" [ StatementList ] . |
| 2798 | SwitchCase = "case" ExpressionList | "default" . |
| 2799 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2800 | |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 2801 | There can be at most one default case in a switch statement. In a case clause, |
| 2802 | the last statement only may be a fallthrough statement ($Fallthrough statement). |
| 2803 | It indicates that the control should flow from the end of this case clause to |
| 2804 | the first statement of the next clause. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2805 | <p> |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 2806 | Each case clause effectively acts as a block for scoping purposes |
| 2807 | ($Declarations and scope rules). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2808 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2809 | The expressions do not need to be constants. They will |
| 2810 | be evaluated top to bottom until the first successful non-default case is reached. |
| 2811 | If none matches and there is a default case, the statements of the default |
| 2812 | case are executed. |
| 2813 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2814 | <pre> |
| 2815 | switch tag { |
| 2816 | default: s3() |
| 2817 | case 0, 1: s1() |
| 2818 | case 2: s2() |
| 2819 | } |
| 2820 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2821 | |
| 2822 | A switch statement may include the declaration of a single temporary variable. |
| 2823 | The scope of the declared variable extends to the end of the switch statement, and |
| 2824 | the variable is initialized once before the switch is entered. |
| 2825 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2826 | <pre> |
| 2827 | switch x := f(); true { |
| 2828 | case x < 0: return -x |
| 2829 | default: return x |
| 2830 | } |
| 2831 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2832 | |
| 2833 | Cases do not fall through unless explicitly marked with a "fallthrough" statement. |
| 2834 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2835 | <pre> |
| 2836 | switch a { |
| 2837 | case 1: |
| 2838 | b(); |
| 2839 | fallthrough |
| 2840 | case 2: |
| 2841 | c(); |
| 2842 | } |
| 2843 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2844 | |
| 2845 | If the expression is omitted, it is equivalent to "true". |
| 2846 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2847 | <pre> |
| 2848 | switch { |
| 2849 | case x < y: f1(); |
| 2850 | case x < z: f2(); |
| 2851 | case x == 4: f3(); |
| 2852 | } |
| 2853 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2854 | |
| 2855 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2856 | <h3>For statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2857 | |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2858 | A for statement specifies repeated execution of a block. The iteration is |
| 2859 | controlled by a condition, a for clause, or a range clause. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2860 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2861 | <pre> |
| 2862 | ForStat = "for" [ Condition | ForClause | RangeClause ] Block . |
| 2863 | Condition = Expression . |
| 2864 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2865 | |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2866 | In its simplest form, a for statement specifies the repeated execution of |
| 2867 | a block as long as a condition evaluates to true. The condition is evaluated |
| 2868 | before each iteration. The type of the condition expression must be boolean. |
| 2869 | If the condition is absent, it is equivalent to "true". |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2870 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2871 | <pre> |
| 2872 | for a < b { |
| 2873 | a *= 2 |
| 2874 | } |
| 2875 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2876 | |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2877 | A for statement with a for clause is also controlled by its condition, but |
| 2878 | additionally it may specify an init and post statement, such as an assignment, |
| 2879 | an increment or decrement statement. The init statement may also be a (simple) |
| 2880 | variable declaration; no variables can be declared in the post statement. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2881 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2882 | <pre> |
| 2883 | ForClause = [ InitStat ] ";" [ Condition ] ";" [ PostStat ] . |
| 2884 | InitStat = SimpleStat . |
| 2885 | PostStat = SimpleStat . |
| 2886 | </pre> |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2887 | |
| 2888 | For instance, one may declare an iteration variable in the init statement: |
| 2889 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2890 | <pre> |
| 2891 | for i := 0; i < 10; i++ { |
| 2892 | f(i) |
| 2893 | } |
| 2894 | </pre> |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2895 | |
| 2896 | If present, the init statement is executed once before commencing the iteration; |
| 2897 | the post statement is executed after each execution of the statement block (and |
| 2898 | only if the block was executed). The scope of any variable declared in the init |
| 2899 | statement ends with the end of the for statement block ($Declarations and scope |
| 2900 | rules, Rule 3). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2901 | <p> |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2902 | The init and post statement as well as the condition may be omitted; however |
| 2903 | if either the init or post statement are present, the separating semicolons |
| 2904 | must be present. If the condition is absent, it is equivalent to "true". |
| 2905 | The following statements are equivalent: |
| 2906 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2907 | <pre> |
| 2908 | for ; cond ; { S() } is the same as for cond { S() } |
| 2909 | for true { S() } is the same as for { S() } |
| 2910 | </pre> |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2911 | |
| 2912 | Alternatively, a for statement may be controlled by a range clause. A |
| 2913 | range clause specifies iteration through all entries of an array or map. |
| 2914 | For each entry it first assigns the current index or key to an iteration |
| 2915 | variable - or the current (index, element) or (key, value) pair to a pair |
| 2916 | of iteration variables - and then executes the block. Iteration terminates |
| 2917 | when all entries have been processed, or if the for statement is terminated |
| 2918 | early, for instance by a break or return statement. |
| 2919 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2920 | <pre> |
| 2921 | RangeClause = IdentifierList ( "=" | ":=" ) "range" Expression . |
| 2922 | </pre> |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2923 | |
| 2924 | The type of the right-hand expression in the range clause must be an array or |
| 2925 | map, or a pointer to an array or map. If it is a pointer, it must not be nil. |
| 2926 | The left-hand identifier list must contain one or two identifiers denoting the |
| 2927 | iteration variables. The first variable is set to the current array index or |
| 2928 | map key, and the second variable, if present, is set to the corresponding |
| 2929 | array element or map value. The types of the array index (int) and element, |
| 2930 | or of the map key and value respectively, must be assignment-compatible to |
| 2931 | the iteration variables. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2932 | <p> |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2933 | The iteration variables may be declared by the range clause (":="), in which |
| 2934 | case their scope ends at the end of the for statement block ($Declarations and |
| 2935 | scope rules, Rule 3). In this case their types are the array index and element, |
| 2936 | or the map key and value types, respectively. |
| 2937 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2938 | <pre> |
| 2939 | var a [10]string; |
| 2940 | m := map[string]int("mon":0, "tue":1, "wed":2, "thu":3, "fri":4, "sat":5, "sun":6); |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2941 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2942 | for i, s := range a { |
| 2943 | // type of i is int |
| 2944 | // type of s is string |
| 2945 | // s == a[i] |
| 2946 | g(i, s) |
| 2947 | } |
| 2948 | |
| 2949 | var key string; |
| 2950 | var val interface {}; // value type of m is assignment-compatible to val |
| 2951 | for key, value = range m { |
| 2952 | h(key, value) |
| 2953 | } |
| 2954 | // key == last map key encountered in iteration |
| 2955 | // val == map[key] |
| 2956 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2957 | |
Robert Griesemer | 30a1a8c | 2008-12-16 11:38:56 -0800 | [diff] [blame] | 2958 | If map entries that have not yet been processed are deleted during iteration, |
| 2959 | they will not be processed. If map entries are inserted during iteration, the |
| 2960 | behavior is implementation-dependent. Likewise, if the range expression is a |
| 2961 | pointer variable, the behavior of assigning to that variable is implementation- |
| 2962 | dependent. Assigning to the iteration variables during iteration simply changes |
| 2963 | the values of those variables for the current iteration; it does not affect any |
| 2964 | subsequent iterations. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2965 | |
| 2966 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2967 | <h3>Go statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2968 | |
| 2969 | A go statement starts the execution of a function as an independent |
Robert Griesemer | 57b3461 | 2008-10-10 12:45:44 -0700 | [diff] [blame] | 2970 | concurrent thread of control within the same address space. The expression |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 2971 | must be a function or method call. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2972 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2973 | <pre> |
| 2974 | GoStat = "go" Expression . |
| 2975 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2976 | |
Robert Griesemer | b9f8b9c | 2008-09-26 13:38:38 -0700 | [diff] [blame] | 2977 | Unlike with a regular function call, program execution does not wait |
| 2978 | for the invoked function to complete. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2979 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2980 | <pre> |
| 2981 | go Server() |
| 2982 | go func(ch chan <- bool) { for { sleep(10); ch <- true; }} (c) |
| 2983 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2984 | |
| 2985 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2986 | <h3>Select statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2987 | |
| 2988 | A select statement chooses which of a set of possible communications |
| 2989 | will proceed. It looks similar to a switch statement but with the |
| 2990 | cases all referring to communication operations. |
| 2991 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 2992 | <pre> |
| 2993 | SelectStat = "select" "{" { CommClause } "}" . |
| 2994 | CommClause = CommCase ":" [ StatementList ] . |
| 2995 | CommCase = "case" ( SendExpr | RecvExpr) | "default" . |
| 2996 | SendExpr = Expression "<-" Expression . |
| 2997 | RecvExpr = [ Expression ( "=" | ":=" ) ] "<-" Expression . |
| 2998 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 2999 | |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 3000 | Each communication clause acts as a block for the purpose of scoping |
| 3001 | (§Declarations and scope rules). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3002 | <p> |
Rob Pike | 569a107 | 2008-10-03 11:18:45 -0700 | [diff] [blame] | 3003 | For all the send and receive expressions in the select |
| 3004 | statement, the channel expression is evaluated. Any values |
| 3005 | that appear on the right hand side of send expressions are also |
| 3006 | evaluated. If any of the resulting channels can proceed, one is |
| 3007 | chosen and the corresponding communication and statements are |
| 3008 | evaluated. Otherwise, if there is a default case, that executes; |
Rob Pike | cd368a2 | 2008-10-02 10:37:12 -0700 | [diff] [blame] | 3009 | if not, the statement blocks until one of the communications can |
Rob Pike | 569a107 | 2008-10-03 11:18:45 -0700 | [diff] [blame] | 3010 | complete. The channels and send expressions are not re-evaluated. |
| 3011 | A channel pointer may be nil, which is equivalent to that case not |
| 3012 | being present in the select statement. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3013 | <p> |
Rob Pike | 569a107 | 2008-10-03 11:18:45 -0700 | [diff] [blame] | 3014 | Since all the channels and send expressions are evaluated, any side |
| 3015 | effects in that evaluation will occur for all the communications |
| 3016 | in the select. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3017 | <p> |
Robert Griesemer | 2902a82 | 2008-09-17 13:57:11 -0700 | [diff] [blame] | 3018 | If the channel sends or receives an interface type, its |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3019 | communication can proceed only if the type of the communication |
| 3020 | clause matches that of the dynamic value to be exchanged. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3021 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3022 | If multiple cases can proceed, a uniform fair choice is made regarding |
| 3023 | which single communication will execute. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3024 | <p> |
Robert Griesemer | 2902a82 | 2008-09-17 13:57:11 -0700 | [diff] [blame] | 3025 | The receive case may declare a new variable (via a ":=" assignment). The |
| 3026 | scope of such variables begins immediately after the variable identifier |
| 3027 | and ends at the end of the respective "select" case (that is, before the |
| 3028 | next "case", "default", or closing brace). |
| 3029 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3030 | <pre> |
| 3031 | var c, c1, c2 chan int; |
| 3032 | var i1, i2 int; |
| 3033 | select { |
| 3034 | case i1 = <-c1: |
| 3035 | print("received ", i1, " from c1\n"); |
| 3036 | case c2 <- i2: |
| 3037 | print("sent ", i2, " to c2\n"); |
| 3038 | default: |
| 3039 | print("no communication\n"); |
| 3040 | } |
| 3041 | |
| 3042 | for { // send random sequence of bits to c |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3043 | select { |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3044 | case c <- 0: // note: no statement, no fallthrough, no folding of cases |
| 3045 | case c <- 1: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3046 | } |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3047 | } |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3048 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3049 | var ca chan interface {}; |
| 3050 | var i int; |
| 3051 | var f float; |
| 3052 | select { |
| 3053 | case i = <-ca: |
| 3054 | print("received int ", i, " from ca\n"); |
| 3055 | case f = <-ca: |
| 3056 | print("received float ", f, " from ca\n"); |
| 3057 | } |
| 3058 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3059 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3060 | <font color=red> |
Robert Griesemer | 2902a82 | 2008-09-17 13:57:11 -0700 | [diff] [blame] | 3061 | TODO: Make semantics more precise. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3062 | </font> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3063 | |
| 3064 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3065 | <h3>Return statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3066 | |
| 3067 | A return statement terminates execution of the containing function |
| 3068 | and optionally provides a result value or values to the caller. |
| 3069 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3070 | <pre> |
| 3071 | ReturnStat = "return" [ ExpressionList ] . |
| 3072 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3073 | |
| 3074 | |
| 3075 | There are two ways to return values from a function. The first is to |
| 3076 | explicitly list the return value or values in the return statement: |
| 3077 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3078 | <pre> |
| 3079 | func simple_f() int { |
| 3080 | return 2; |
| 3081 | } |
| 3082 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3083 | |
| 3084 | A function may return multiple values. |
| 3085 | The syntax of the return clause in that case is the same as |
| 3086 | that of a parameter list; in particular, names must be provided for |
| 3087 | the elements of the return value. |
| 3088 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3089 | <pre> |
| 3090 | func complex_f1() (re float, im float) { |
| 3091 | return -7.0, -4.0; |
| 3092 | } |
| 3093 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3094 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 3095 | A second method to return values |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3096 | is to use those names within the function as variables |
| 3097 | to be assigned explicitly; the return statement will then provide no |
| 3098 | values: |
| 3099 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3100 | <pre> |
| 3101 | func complex_f2() (re float, im float) { |
| 3102 | re = 7.0; |
| 3103 | im = 4.0; |
| 3104 | return; |
| 3105 | } |
| 3106 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3107 | |
| 3108 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3109 | <h3>Break statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3110 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 3111 | Within a for, switch, or select statement, a break statement terminates |
| 3112 | execution of the innermost such statement. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3113 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3114 | <pre> |
| 3115 | BreakStat = "break" [ identifier ]. |
| 3116 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3117 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 3118 | If there is an identifier, it must be a label marking an enclosing |
| 3119 | for, switch, or select statement, and that is the one whose execution |
| 3120 | terminates. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3121 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3122 | <pre> |
| 3123 | L: for i < n { |
| 3124 | switch i { |
| 3125 | case 5: break L |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3126 | } |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3127 | } |
| 3128 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3129 | |
| 3130 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3131 | <h3>Continue statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3132 | |
| 3133 | Within a for loop a continue statement begins the next iteration of the |
| 3134 | loop at the post statement. |
| 3135 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3136 | <pre> |
| 3137 | ContinueStat = "continue" [ identifier ]. |
| 3138 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3139 | |
| 3140 | The optional identifier is analogous to that of a break statement. |
| 3141 | |
| 3142 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3143 | <h3>Label declarations</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3144 | |
| 3145 | A label declaration serves as the target of a goto, break or continue statement. |
| 3146 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3147 | <pre> |
| 3148 | LabelDecl = identifier ":" . |
| 3149 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3150 | |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 3151 | Example: |
| 3152 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3153 | <pre> |
| 3154 | Error: |
| 3155 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3156 | |
| 3157 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3158 | <h3>Goto statements</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3159 | |
| 3160 | A goto statement transfers control to the corresponding label statement. |
| 3161 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3162 | <pre> |
| 3163 | GotoStat = "goto" identifier . |
| 3164 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3165 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3166 | <pre> |
| 3167 | goto Error |
| 3168 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3169 | |
| 3170 | Executing the goto statement must not cause any variables to come into |
| 3171 | scope that were not already in scope at the point of the goto. For |
| 3172 | instance, this example: |
| 3173 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3174 | <pre> |
| 3175 | goto L; // BAD |
| 3176 | v := 3; |
| 3177 | L: |
| 3178 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3179 | |
| 3180 | is erroneous because the jump to label L skips the creation of v. |
| 3181 | |
| 3182 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3183 | <h3>Fallthrough statements</h3> |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 3184 | |
| 3185 | A fallthrough statement transfers control to the first statement of the |
| 3186 | next case clause in a switch statement (§Switch statements). It may only |
| 3187 | be used in a switch statement, and only as the last statement in a case |
| 3188 | clause of the switch statement. |
| 3189 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3190 | <pre> |
| 3191 | FallthroughStat = "fallthrough" . |
| 3192 | </pre> |
Robert Griesemer | aed247f | 2008-10-08 17:05:30 -0700 | [diff] [blame] | 3193 | |
| 3194 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3195 | <h3>Defer statements</h3> |
Robert Griesemer | 4a903e0 | 2009-01-27 09:29:40 -0800 | [diff] [blame] | 3196 | |
| 3197 | A defer statement invokes a function whose execution is deferred to the moment |
| 3198 | when the surrounding function returns. |
| 3199 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3200 | <pre> |
| 3201 | DeferStat = "defer" Expression . |
| 3202 | </pre> |
Robert Griesemer | 4a903e0 | 2009-01-27 09:29:40 -0800 | [diff] [blame] | 3203 | |
Robert Griesemer | 7471eab | 2009-01-27 14:51:24 -0800 | [diff] [blame] | 3204 | The expression must be a function or method call. Each time the defer statement |
| 3205 | executes, the parameters to the function call are evaluated and saved anew but the |
Robert Griesemer | 4a903e0 | 2009-01-27 09:29:40 -0800 | [diff] [blame] | 3206 | function is not invoked. Immediately before the innermost function surrounding |
| 3207 | the defer statement returns, but after its return value (if any) is evaluated, |
| 3208 | each deferred function is executed with its saved parameters. Deferred functions |
| 3209 | are executed in LIFO order. |
| 3210 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3211 | <pre> |
| 3212 | lock(l); |
| 3213 | defer unlock(l); // unlocking happens before surrounding function returns |
Robert Griesemer | 4a903e0 | 2009-01-27 09:29:40 -0800 | [diff] [blame] | 3214 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3215 | // prints 3 2 1 0 before surrounding function returns |
| 3216 | for i := 0; i <= 3; i++ { |
| 3217 | defer fmt.Print(i); |
| 3218 | } |
| 3219 | </pre> |
Robert Griesemer | 4a903e0 | 2009-01-27 09:29:40 -0800 | [diff] [blame] | 3220 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3221 | <hr> |
Robert Griesemer | 4a903e0 | 2009-01-27 09:29:40 -0800 | [diff] [blame] | 3222 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3223 | <h2>Function declarations</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3224 | |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 3225 | A function declaration binds an identifier to a function. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3226 | Functions contain declarations and statements. They may be |
Robert Griesemer | 7abfcd9 | 2008-10-07 17:14:30 -0700 | [diff] [blame] | 3227 | recursive. Except for forward declarations (see below), the parameter |
Robert Griesemer | 2b9fe0e | 2009-01-30 14:48:29 -0800 | [diff] [blame] | 3228 | and result types of the signature must all be complete types (§Type declarations). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3229 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3230 | <pre> |
| 3231 | FunctionDecl = "func" identifier Signature [ Block ] . |
| 3232 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3233 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3234 | <pre> |
| 3235 | func min(x int, y int) int { |
| 3236 | if x < y { |
| 3237 | return x; |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3238 | } |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3239 | return y; |
| 3240 | } |
| 3241 | </pre> |
Robert Griesemer | 667ef6c | 2008-09-10 13:00:32 -0700 | [diff] [blame] | 3242 | |
Robert Griesemer | ad71110 | 2008-09-11 17:48:20 -0700 | [diff] [blame] | 3243 | A function declaration without a block serves as a forward declaration: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3244 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3245 | <pre> |
| 3246 | func MakeNode(left, right *Node) *Node |
| 3247 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3248 | |
| 3249 | |
Robert Griesemer | 667ef6c | 2008-09-10 13:00:32 -0700 | [diff] [blame] | 3250 | Implementation restrictions: Functions can only be declared at the global level. |
| 3251 | A function must be declared or forward-declared before it can be invoked. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3252 | |
| 3253 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3254 | <h3>Method declarations</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3255 | |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 3256 | A method declaration is a function declaration with a receiver. The receiver |
| 3257 | is the first parameter of the method, and the receiver type must be specified |
| 3258 | as a type name, or as a pointer to a type name. The type specified by the |
| 3259 | type name is called ``receiver base type''. The receiver base type must be a |
Robert Griesemer | a1065fa | 2008-09-29 20:37:46 -0700 | [diff] [blame] | 3260 | type declared in the current file, and it must not be a pointer type. |
| 3261 | The method is said to be ``bound'' to the receiver base type; specifically |
Robert Griesemer | 6ccca61 | 2008-12-18 13:29:11 -0800 | [diff] [blame] | 3262 | it is declared within the scope of that type (§Type declarations). If the |
| 3263 | receiver value is not needed inside the method, its identifier may be omitted |
| 3264 | in the declaration. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3265 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3266 | <pre> |
| 3267 | MethodDecl = "func" Receiver identifier Signature [ Block ] . |
| 3268 | Receiver = "(" [ identifier ] [ "*" ] TypeName ")" . |
| 3269 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3270 | |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 3271 | All methods bound to a receiver base type must have the same receiver type: |
| 3272 | Either all receiver types are pointers to the base type or they are the base |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3273 | type. <font color=red> |
| 3274 | (TODO: This restriction can be relaxed at the cost of more complicated |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 3275 | assignment rules to interface types). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3276 | </font> |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 3277 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3278 | For instance, given type Point, the declarations |
| 3279 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3280 | <pre> |
| 3281 | func (p *Point) Length() float { |
| 3282 | return Math.sqrt(p.x * p.x + p.y * p.y); |
| 3283 | } |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3284 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3285 | func (p *Point) Scale(factor float) { |
| 3286 | p.x = p.x * factor; |
| 3287 | p.y = p.y * factor; |
| 3288 | } |
| 3289 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3290 | |
Robert Griesemer | 1f3e842 | 2008-09-29 18:41:30 -0700 | [diff] [blame] | 3291 | bind the methods "Length" and "Scale" to the receiver base type "Point". |
| 3292 | |
| 3293 | Method declarations may appear anywhere after the declaration of the receiver |
| 3294 | base type and may be forward-declared. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3295 | |
| 3296 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3297 | <h3>Predeclared functions</h3> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3298 | <ul> |
| 3299 | <li>cap |
| 3300 | <li>convert |
| 3301 | <li>len |
| 3302 | <li>make |
| 3303 | <li>new |
| 3304 | <li>panic |
| 3305 | <li>panicln |
| 3306 | <li>print |
| 3307 | <li>println |
| 3308 | <li>typeof |
| 3309 | </ul> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3310 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3311 | <h3>Length and capacity</h3> |
Robert Griesemer | 7a4ed4f | 2008-09-03 15:15:51 -0700 | [diff] [blame] | 3312 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3313 | <pre> |
| 3314 | Call Argument type Result |
Robert Griesemer | 7a4ed4f | 2008-09-03 15:15:51 -0700 | [diff] [blame] | 3315 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3316 | len(s) string, *string string length (in bytes) |
| 3317 | [n]T, *[n]T array length (== n) |
| 3318 | []T, *[]T slice length |
| 3319 | map[K]T, *map[K]T map length |
| 3320 | chan T number of elements in channel buffer |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 3321 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3322 | cap(s) []T, *[]T capacity of s |
| 3323 | map[K]T, *map[K]T capacity of s |
| 3324 | chan T channel buffer capacity |
| 3325 | </pre> |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 3326 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3327 | <font color=red> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3328 | TODO: confirm len() and cap() for channels |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3329 | </font> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3330 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3331 | <p> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3332 | The type of the result is always "int" and the implementation guarantees that |
| 3333 | the result always fits into an "int". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3334 | <p> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3335 | The capacity of a slice or map is the number of elements for which there is |
| 3336 | space allocated in the underlying array (for a slice) or map. For a slice "s", |
| 3337 | at any time the following relationship holds: |
| 3338 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3339 | <pre> |
| 3340 | 0 <= len(s) <= cap(s) |
| 3341 | </pre> |
Robert Griesemer | 667ef6c | 2008-09-10 13:00:32 -0700 | [diff] [blame] | 3342 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 3343 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3344 | <h3>Conversions</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3345 | |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3346 | Conversions syntactically look like function calls of the form |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3347 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3348 | <pre> |
| 3349 | T(value) |
| 3350 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3351 | |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3352 | where "T" is the type name of an arithmetic type or string (§Basic types), |
| 3353 | and "value" is the value of an expression which can be converted to a value |
| 3354 | of result type "T". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3355 | <p> |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3356 | The following conversion rules apply: |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3357 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3358 | 1) Between integer types. If the value is a signed quantity, it is |
| 3359 | sign extended to implicit infinite precision; otherwise it is zero |
| 3360 | extended. It is then truncated to fit in the result type size. |
| 3361 | For example, uint32(int8(0xFF)) is 0xFFFFFFFF. The conversion always |
| 3362 | yields a valid value; there is no signal for overflow. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3363 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3364 | 2) Between integer and floating point types, or between floating point |
| 3365 | types. To avoid overdefining the properties of the conversion, for |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 3366 | now it is defined as a ``best effort'' conversion. The conversion |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3367 | always succeeds but the value may be a NaN or other problematic |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3368 | result. <font color=red>TODO: clarify?</font> |
| 3369 | <p> |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3370 | 3) Strings permit two special conversions. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3371 | <p> |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3372 | 3a) Converting an integer value yields a string containing the UTF-8 |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3373 | representation of the integer. |
| 3374 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3375 | <pre> |
| 3376 | string(0x65e5) // "\u65e5" |
| 3377 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3378 | |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3379 | 3b) Converting an array of uint8s yields a string whose successive |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3380 | bytes are those of the array. (Recall byte is a synonym for uint8.) |
| 3381 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3382 | <pre> |
| 3383 | string([]byte('h', 'e', 'l', 'l', 'o')) // "hello" |
| 3384 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3385 | |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3386 | There is no linguistic mechanism to convert between pointers |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3387 | and integers. A library may be provided under restricted circumstances |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3388 | to acccess this conversion in low-level code. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3389 | <p> |
| 3390 | <font color=red> |
Robert Griesemer | 133c68e | 2008-09-26 14:04:21 -0700 | [diff] [blame] | 3391 | TODO: Do we allow interface/ptr conversions in this form or do they |
| 3392 | have to be written as type guards? (§Type guards) |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3393 | </font> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3394 | |
| 3395 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3396 | <h3>Allocation</h3> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3397 | |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3398 | The built-in function "new" takes a type "T" and returns a value of type "*T". |
Robert Griesemer | a329471 | 2009-01-05 11:17:26 -0800 | [diff] [blame] | 3399 | The memory is initialized as described in the section on initial values |
Robert Griesemer | 434c605 | 2008-11-07 13:34:37 -0800 | [diff] [blame] | 3400 | (§Program initialization and execution). |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3401 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3402 | <pre> |
| 3403 | new(T) |
| 3404 | </pre> |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 3405 | |
| 3406 | For instance |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3407 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3408 | <pre> |
| 3409 | type S struct { a int; b float } |
| 3410 | new(S) |
| 3411 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3412 | |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 3413 | dynamically allocates memory for a variable of type S, initializes it |
| 3414 | (a=0, b=0.0), and returns a value of type *S pointing to that variable. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3415 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3416 | <p> |
| 3417 | <font color=red> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3418 | TODO Once this has become clearer, connect new() and make() (new() may be |
| 3419 | explained by make() and vice versa). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3420 | </font> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3421 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3422 | <h3>Making slices, maps, and channels</h3> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3423 | |
| 3424 | The built-in function "make" takes a type "T", optionally followed by a |
| 3425 | type-specific list of expressions. It returns a value of type "T". "T" |
| 3426 | must be a slice, map, or channel type. |
| 3427 | The memory is initialized as described in the section on initial values |
| 3428 | (§Program initialization and execution). |
| 3429 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3430 | <pre> |
| 3431 | make(T [, optional list of expressions]) |
| 3432 | </pre> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3433 | |
| 3434 | For instance |
| 3435 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3436 | <pre> |
| 3437 | make(map[string] int) |
| 3438 | </pre> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3439 | |
| 3440 | creates a new map value and initializes it to an empty map. |
| 3441 | |
| 3442 | The only defined parameters affect sizes for allocating slices, maps, and |
| 3443 | buffered channels: |
| 3444 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3445 | <pre> |
| 3446 | s := make([]int, 10, 100); # slice with len(s) == 10, cap(s) == 100 |
| 3447 | c := make(chan int, 10); # channel with a buffer size of 10 |
| 3448 | m := make(map[string] int, 100); # map with initial space for 100 elements |
| 3449 | </pre> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3450 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3451 | <font color=red> |
Robert Griesemer | 633957b | 2009-01-06 13:23:20 -0800 | [diff] [blame] | 3452 | TODO Once this has become clearer, connect new() and make() (new() may be |
| 3453 | explained by make() and vice versa). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3454 | </font> |
Robert Griesemer | ebf14c6 | 2008-10-30 14:50:23 -0700 | [diff] [blame] | 3455 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3456 | <hr> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3457 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3458 | <h2>Packages</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3459 | |
| 3460 | A package is a package clause, optionally followed by import declarations, |
| 3461 | followed by a series of declarations. |
| 3462 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3463 | <pre> |
| 3464 | Package = PackageClause { ImportDecl [ ";" ] } { Declaration [ ";" ] } . |
| 3465 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3466 | |
Robert Griesemer | 347cf67 | 2008-10-03 14:04:28 -0700 | [diff] [blame] | 3467 | The source text following the package clause acts like a block for scoping |
| 3468 | purposes ($Declarations and scope rules). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3469 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3470 | Every source file identifies the package to which it belongs. |
| 3471 | The file must begin with a package clause. |
| 3472 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3473 | <pre> |
| 3474 | PackageClause = "package" PackageName . |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3475 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3476 | package Math |
| 3477 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3478 | |
| 3479 | |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 3480 | A package can gain access to exported identifiers from another package |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3481 | through an import declaration: |
| 3482 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3483 | <pre> |
| 3484 | ImportDecl = "import" ( ImportSpec | "(" [ ImportSpecList ] ")" ) . |
| 3485 | ImportSpecList = ImportSpec { ";" ImportSpec } [ ";" ] . |
| 3486 | ImportSpec = [ "." | PackageName ] PackageFileName . |
| 3487 | PackageFileName = StringLit . |
| 3488 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3489 | |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 3490 | An import statement makes the exported top-level identifiers of the named |
| 3491 | package file accessible to this package. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3492 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3493 | In the following discussion, assume we have a package in the |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 3494 | file "/lib/math", called package "math", which exports the identifiers |
| 3495 | "Sin" and "Cos" denoting the respective trigonometric functions. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3496 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3497 | In the general form, with an explicit package name, the import |
| 3498 | statement declares that package name as an identifier whose |
| 3499 | contents are the exported elements of the imported package. |
| 3500 | For instance, after |
| 3501 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3502 | <pre> |
| 3503 | import M "/lib/math" |
| 3504 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3505 | |
| 3506 | the contents of the package /lib/math can be accessed by |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 3507 | "M.Sin", "M.Cos", etc. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3508 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3509 | In its simplest form, with no package name, the import statement |
| 3510 | implicitly uses the imported package name itself as the local |
| 3511 | package name. After |
| 3512 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3513 | <pre> |
| 3514 | import "/lib/math" |
| 3515 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3516 | |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 3517 | the contents are accessible by "math.Sin", "math.Cos". |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3518 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3519 | Finally, if instead of a package name the import statement uses |
| 3520 | an explicit period, the contents of the imported package are added |
| 3521 | to the current package. After |
| 3522 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3523 | <pre> |
| 3524 | import . "/lib/math" |
| 3525 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3526 | |
Robert Griesemer | 83c1760 | 2009-01-16 14:12:50 -0800 | [diff] [blame] | 3527 | the contents are accessible by "Sin" and "Cos". In this instance, it is |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3528 | an error if the import introduces name conflicts. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3529 | <p> |
Robert Griesemer | 7a4ed4f | 2008-09-03 15:15:51 -0700 | [diff] [blame] | 3530 | Here is a complete example Go package that implements a concurrent prime sieve: |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3531 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3532 | <pre> |
| 3533 | package main |
| 3534 | |
| 3535 | // Send the sequence 2, 3, 4, ... to channel 'ch'. |
| 3536 | func generate(ch chan <- int) { |
| 3537 | for i := 2; ; i++ { |
| 3538 | ch <- i // Send 'i' to channel 'ch'. |
| 3539 | } |
| 3540 | } |
| 3541 | |
| 3542 | // Copy the values from channel 'in' to channel 'out', |
| 3543 | // removing those divisible by 'prime'. |
| 3544 | func filter(in chan <- int, out *<-chan int, prime int) { |
| 3545 | for { |
| 3546 | i := <-in; // Receive value of new variable 'i' from 'in'. |
| 3547 | if i % prime != 0 { |
| 3548 | out <- i // Send 'i' to channel 'out'. |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3549 | } |
| 3550 | } |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3551 | } |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3552 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3553 | // The prime sieve: Daisy-chain filter processes together. |
| 3554 | func sieve() { |
| 3555 | ch := make(chan int); // Create a new channel. |
| 3556 | go generate(ch); // Start generate() as a subprocess. |
| 3557 | for { |
| 3558 | prime := <-ch; |
| 3559 | print(prime, "\n"); |
| 3560 | ch1 := make(chan int); |
| 3561 | go filter(ch, ch1, prime); |
| 3562 | ch = ch1 |
| 3563 | } |
| 3564 | } |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3565 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3566 | func main() { |
| 3567 | sieve() |
| 3568 | } |
| 3569 | </pre> |
Robert Griesemer | 6715358 | 2008-12-16 14:45:09 -0800 | [diff] [blame] | 3570 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3571 | <hr> |
| 3572 | |
| 3573 | <h2>Program initialization and execution</h2> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3574 | |
| 3575 | When memory is allocated to store a value, either through a declaration |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 3576 | or "new()", and no explicit initialization is provided, the memory is |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3577 | given a default initialization. Each element of such a value is |
| 3578 | set to the ``zero'' for that type: "false" for booleans, "0" for integers, |
Robert Griesemer | 52a5480 | 2008-09-30 13:02:50 -0700 | [diff] [blame] | 3579 | "0.0" for floats, '''' for strings, and "nil" for pointers and interfaces. |
| 3580 | This intialization is done recursively, so for instance each element of an |
| 3581 | array of integers will be set to 0 if no other value is specified. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3582 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3583 | These two simple declarations are equivalent: |
| 3584 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3585 | <pre> |
| 3586 | var i int; |
| 3587 | var i int = 0; |
| 3588 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3589 | |
| 3590 | After |
| 3591 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3592 | <pre> |
| 3593 | type T struct { i int; f float; next *T }; |
| 3594 | t := new(T); |
| 3595 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3596 | |
| 3597 | the following holds: |
| 3598 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3599 | <pre> |
| 3600 | t.i == 0 |
| 3601 | t.f == 0.0 |
| 3602 | t.next == nil |
| 3603 | </pre> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3604 | |
| 3605 | |
| 3606 | A package with no imports is initialized by assigning initial values to |
| 3607 | all its global variables in declaration order and then calling any init() |
| 3608 | functions defined in its source. Since a package may contain more |
| 3609 | than one source file, there may be more than one init() function, but |
| 3610 | only one per source file. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3611 | <p> |
Robert Griesemer | 566e3b2 | 2008-09-26 16:41:50 -0700 | [diff] [blame] | 3612 | Initialization code may contain "go" statements, but the functions |
Robert Griesemer | d8a764c | 2009-02-06 17:01:10 -0800 | [diff] [blame] | 3613 | they invoke do not begin execution until initialization of the entire |
| 3614 | program is complete. Therefore, all initialization code is run in a single |
| 3615 | thread of execution. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3616 | <p> |
Robert Griesemer | 566e3b2 | 2008-09-26 16:41:50 -0700 | [diff] [blame] | 3617 | Furthermore, an "init()" function cannot be referred to from anywhere |
| 3618 | in a program. In particular, "init()" cannot be called explicitly, nor |
| 3619 | can a pointer to "init" be assigned to a function variable). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3620 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3621 | If a package has imports, the imported packages are initialized |
Robert Griesemer | 566e3b2 | 2008-09-26 16:41:50 -0700 | [diff] [blame] | 3622 | before initializing the package itself. If multiple packages import |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3623 | a package P, P will be initialized only once. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3624 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3625 | The importing of packages, by construction, guarantees that there can |
| 3626 | be no cyclic dependencies in initialization. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3627 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3628 | A complete program, possibly created by linking multiple packages, |
| 3629 | must have one package called main, with a function |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 3630 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3631 | <pre> |
| 3632 | func main() { ... } |
| 3633 | </pre> |
Robert Griesemer | 4dc2528 | 2008-09-09 10:37:19 -0700 | [diff] [blame] | 3634 | |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3635 | defined. The function main.main() takes no arguments and returns no |
| 3636 | value. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3637 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3638 | Program execution begins by initializing the main package and then |
| 3639 | invoking main.main(). |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3640 | <p> |
Robert Griesemer | df49fb3 | 2008-08-28 17:47:53 -0700 | [diff] [blame] | 3641 | When main.main() returns, the program exits. |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3642 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3643 | <hr> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3644 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3645 | <h2>Systems considerations</h2> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3646 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3647 | <h3>Package unsafe</h3> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3648 | |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 3649 | The built-in package "unsafe", known to the compiler, provides facilities |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3650 | for low-level programming including operations that violate the Go type |
| 3651 | system. A package using "unsafe" must be vetted manually for type safety. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3652 | <p> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3653 | The package "unsafe" provides (at least) the following package interface: |
| 3654 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3655 | <pre> |
| 3656 | package unsafe |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3657 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3658 | const Maxalign int |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3659 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3660 | type Pointer *any |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3661 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3662 | func Alignof(variable any) int |
| 3663 | func Offsetof(selector any) int |
| 3664 | func Sizeof(variable any) int |
| 3665 | </pre> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3666 | |
| 3667 | The pseudo type "any" stands for any Go type; "any" is not a type generally |
| 3668 | available in Go programs. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3669 | <p> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3670 | Any pointer type as well as values of type "uintptr" can be converted into |
| 3671 | an "unsafe.Pointer" and vice versa. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3672 | <p> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3673 | The function "Sizeof" takes an expression denoting a variable of any type |
| 3674 | and returns the size of the variable in bytes. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3675 | <p> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3676 | The function "Offsetof" takes a selector (§Selectors) denoting a struct |
| 3677 | field of any type and returns the field offset in bytes relative to the |
| 3678 | struct address. Specifically, the following condition is satisfied for |
| 3679 | a struct "s" with field "f": |
| 3680 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3681 | <pre> |
| 3682 | uintptr(unsafe.Pointer(&s)) + uintptr(unsafe.Offsetof(s.f)) == |
| 3683 | uintptr(unsafe.Pointer(&s.f)) |
| 3684 | </pre> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3685 | |
| 3686 | Computer architectures may impose restrictions on the memory addresses accessed |
| 3687 | directly by machine instructions. A common such restriction is the requirement |
| 3688 | for such addresses to be ``aligned''; that is, addresses must be a multiple |
| 3689 | of a factor, the ``alignment''. The alignment depends on the type of datum |
| 3690 | accessed. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3691 | <p> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3692 | The function "Alignof" takes an expression denoting a variable of any type |
| 3693 | and returns the alignment of the variable in bytes. The following alignment |
| 3694 | condition is satisfied for a variable "x": |
| 3695 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3696 | <pre> |
| 3697 | uintptr(unsafe.Pointer(&x)) % uintptr(unsafe.Alignof(x)) == 0 |
| 3698 | </pre> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3699 | |
| 3700 | The maximum alignment is given by the constant "unsafe.Maxalign". |
| 3701 | It usually corresponds to the value of "unsafe.Sizeof(x)" for |
| 3702 | a variable "x" of the largest arithmetic type (8 for a float64), but may |
| 3703 | be smaller on systems that have less stringent alignment restrictions |
| 3704 | or are space constrained. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3705 | <p> |
Robert Griesemer | 6f8df7a | 2009-02-11 21:57:15 -0800 | [diff] [blame] | 3706 | The results of calls to "unsafe.Alignof", "unsafe.Offsetof", and |
| 3707 | "unsafe.Sizeof" are compile-time constants. |
| 3708 | |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3709 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3710 | <h3>Size and alignment guarantees</h3> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3711 | |
| 3712 | For the arithmetic types (§Arithmetic types), a Go compiler guarantees the |
| 3713 | following sizes: |
| 3714 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3715 | <pre> |
| 3716 | type size in bytes |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3717 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3718 | byte, uint8, int8 1 |
| 3719 | uint16, int16 2 |
| 3720 | uint32, int32, float32 4 |
| 3721 | uint64, int64, float64 8 |
| 3722 | </pre> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3723 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3724 | <p> |
Rob Pike | 4501d34 | 2009-02-19 17:31:36 -0800 | [diff] [blame] | 3725 | A Go compiler guarantees the following minimal alignment properties: |
| 3726 | </p> |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3727 | <ol> |
| 3728 | <li>For a variable "x" of any type: "1 <= unsafe.Alignof(x) <= unsafe.Maxalign". |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3729 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3730 | <li>For a variable "x" of arithmetic type: "unsafe.Alignof(x)" is the smaller |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3731 | of "unsafe.Sizeof(x)" and "unsafe.Maxalign", but at least 1. |
| 3732 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3733 | <li>For a variable "x" of struct type: "unsafe.Alignof(x)" is the largest of |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3734 | all the values "unsafe.Alignof(x.f)" for each field "f" of x, but at least 1. |
| 3735 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3736 | <li>For a variable "x" of array type: "unsafe.Alignof(x)" is the same as |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3737 | unsafe.Alignof(x[0]), but at least 1. |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3738 | </ol> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3739 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3740 | <hr> |
Robert Griesemer | 52c02c2 | 2009-02-11 13:46:30 -0800 | [diff] [blame] | 3741 | |
Robert Griesemer | c2d5586 | 2009-02-19 16:49:10 -0800 | [diff] [blame] | 3742 | </div> |
| 3743 | </body> |
| 3744 | </html> |