基础语法

如下是一个程序的基本组成结构:

  1. // 当前程序的包名, main包表示入口包, 是编译构建的入口
  2. package main
  3. // 导入其他包
  4. import "fmt"
  5. // 常量定义
  6. const PI = 3.1415
  7. // 全局变量声明和赋值
  8. var name = "fly"
  9. // 一般类型声明
  10. type newType int
  11. // 结构体声明
  12. type student struct{}
  13. // 接口声明
  14. type reader interface{}
  15. // 程序入口
  16. func main() {
  17. fmt.Println("hello world, this is my first golang program!")
  18. }

在这个结构里面必须要符合Go程序的语法, 编写出来的程序才是合法的,才能被编译器识别, 编译器识别代码的基础单位是Lexical Token(词法标记),比如 如下一段代码:

  1. func main() {
  2. fmt.Println("hello world, this is my first golang program!")
  3. }

他包含的Lexical Token(词法标记),有如下12个:

  1. func // 关键字 func
  2. main // 标识符 函数名称
  3. ( // LPAREN 左小括号
  4. { // LBRACE 左花括号
  5. fmt // 标识符 包名称
  6. . // PERIOD 调用符
  7. Println // 标识符 函数名称
  8. ( // LPAREN 左小括号
  9. "hello world, this is my first golang program!" // 标识符 字符串常量
  10. ) // RPAREN 右小括号
  11. } // RBRACE 右花括号
  12. ) // LPAREN 右小括号

非法的词法

ILLEGAL: 标识非法的词法
比如如下一段代码:

  1. func main() {
  2. 中文
  3. }

这个中文就是一个非法的词法, 编译的时候会直接报错

  1. src\day1\hello.go:8:2: undefined: 中文

流结束

EOF: 用于标识 流(io stream)结束
比如parser/parser.go会重复解析声明到文件的最后:

  1. for p.tok != token.EOF {
  2. decls = append(decls, p.parseDecl(declStart))
  3. }

注释

COMMENT:注释
Go 支持两种注释方式,行注释和块注释:

  • 行注释:以//开头,例如: //我是行注释
  • 块注释:以/开头,以/结尾,例如:/我是块注释/
  1. // 这是一个行注释
  2. /*
  3. 这是一个块注释
  4. */

行分隔符

行分隔符为: ;
但是我们写程序的时候往往都不需要收到写;, 比如Hello world里面的打印语句

  1. fmt.Println("Hello World!")

这是因为Go语言的编译器会自动为我们添加

如果你打算将多个语句写在同一行,它们则必须使用 ; 人为区分,但在实际开发中我们并不鼓励这种做法。
而且go fmt 会自动帮你分成2行

  1. fmt.Println("Hello World!");fmt.Println("Hello World!")

标识符

标识符用来命名变量、类型等程序实体,一个标识符实际上就是一个或是多个字母(AZ和az)数字(0~9)、下划线_组成的序列,但是第一个字符必须是字母或下划线而不能是数字

Go 语言标识符的命名规则如下:

  • 只能由非空字母(Unicode)、数字、下划线(_)组成
  • 只能以字母或下划线开头
  • 不能 Go 语言关键字
  • 避免使用 Go 语言预定义标识符
  • 建议使用驼峰式
  • 标识符区分大小写

下面这些就是一些合法的标识符

  1. username xxx M user_name user1
  2. _temp temp_ heelo1 MMXXX 中文

比如这段代码是合法的

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. 中文 := "你好,中文"
  7. fmt.Println(中文)
  8. }

而下面这些就是一个非法的标识符

  1. 1user // 数字打头
  2. for // 关键字不能作为标识符
  3. m*m // 运算符是不允许的
  4. // 有空格

下面这段代码就会报错

  1. package main
  2. import (
  3. "fmt"
  4. )
  5. func main() {
  6. m*2 := "stirng"
  7. fmt.Println(m*2)
  8. }

扩展

go 语言支持的所有词法标记如下:

  1. var tokens = [...]string{
  2. // 特殊词法
  3. ILLEGAL: "ILLEGAL",
  4. EOF: "EOF",
  5. COMMENT: "COMMENT",
  6. // 标识符
  7. IDENT: "IDENT",
  8. // 基本类型
  9. INT: "INT",
  10. FLOAT: "FLOAT",
  11. IMAG: "IMAG",
  12. CHAR: "CHAR",
  13. STRING: "STRING",
  14. // 操作符
  15. ADD: "+",
  16. SUB: "-",
  17. MUL: "*",
  18. QUO: "/",
  19. REM: "%",
  20. AND: "&",
  21. OR: "|",
  22. XOR: "^",
  23. SHL: "<<",
  24. SHR: ">>",
  25. AND_NOT: "&^",
  26. ADD_ASSIGN: "+=",
  27. SUB_ASSIGN: "-=",
  28. MUL_ASSIGN: "*=",
  29. QUO_ASSIGN: "/=",
  30. REM_ASSIGN: "%=",
  31. AND_ASSIGN: "&=",
  32. OR_ASSIGN: "|=",
  33. XOR_ASSIGN: "^=",
  34. SHL_ASSIGN: "<<=",
  35. SHR_ASSIGN: ">>=",
  36. AND_NOT_ASSIGN: "&^=",
  37. LAND: "&&",
  38. LOR: "||",
  39. ARROW: "<-",
  40. INC: "++",
  41. DEC: "--",
  42. EQL: "==",
  43. LSS: "<",
  44. GTR: ">",
  45. ASSIGN: "=",
  46. NOT: "!",
  47. NEQ: "!=",
  48. LEQ: "<=",
  49. GEQ: ">=",
  50. DEFINE: ":=",
  51. ELLIPSIS: "...",
  52. LPAREN: "(",
  53. LBRACK: "[",
  54. LBRACE: "{",
  55. COMMA: ",",
  56. PERIOD: ".",
  57. RPAREN: ")",
  58. RBRACK: "]",
  59. RBRACE: "}",
  60. SEMICOLON: ";",
  61. COLON: ":",
  62. // 25个关键字
  63. BREAK: "break",
  64. CASE: "case",
  65. CHAN: "chan",
  66. CONST: "const",
  67. CONTINUE: "continue",
  68. DEFAULT: "default",
  69. DEFER: "defer",
  70. ELSE: "else",
  71. FALLTHROUGH: "fallthrough",
  72. FOR: "for",
  73. FUNC: "func",
  74. GO: "go",
  75. GOTO: "goto",
  76. IF: "if",
  77. IMPORT: "import",
  78. INTERFACE: "interface",
  79. MAP: "map",
  80. PACKAGE: "package",
  81. RANGE: "range",
  82. RETURN: "return",
  83. SELECT: "select",
  84. STRUCT: "struct",
  85. SWITCH: "switch",
  86. TYPE: "type",
  87. VAR: "var",
  88. }