返回介绍

上卷 程序设计

中卷 标准库

下卷 运行时

源码剖析

附录

3. 语句

发布于 2024-10-12 19:15:47 字数 3376 浏览 0 评论 0 收藏 0

语句 (statement)执行一到多个动作, 表达式 (expression)计算并返回结果。
表达式属于语句,而语句未见得是表达式。

关键字

仅 25 个 保留关键字 (keywords),体现语法规则的简洁性。
保留关键字不能用作常量、变量、函数名以及结构字段等标识符。

break        default       func        interface   select
case         defer         go          map         struct
chan         else          goto        package     switch
const        fallthrough   if          range       type
continue     for           import      return      var

符号

符号列表。其中,自增( ++ )、自减( -- )是语句,且没有三元运算符( ?: )。

+      &       +=      &=       &&      ==      !=      (      )
-      |       -=      |=       ||      <       <=      [      ]
*      ^       *=      ^=       <-      >       >=      {      }
/      <<      /=      <<=      ++      =       :=      ,      ;
%      >>      %=      >>=      --      !       ...     .      :
       &^              &^=              ~

提示: ^ 即是一元 NOT ,也是二元 XOR 。而 ~ 为泛型新增。

二元

一元优先级最高,二元分五个级别。相同优先级的二元运算符,从左往右依次计算。

highest 	 *     /     %     <<    >>    &    &^
 	         +     -     |     ^ 
 	         ==    !=    <     <=    >     >=
 	         &&
lowest	   ||

除位移外,二元操作数类型必须相同。

func main() {
    var a int
    var b int64
    
    // _ = a + b
    //     ~~~~~ invalid operation: mismatched types int and int64
}

位移右操作数是整数类型,或可转换的无类型常量。

func main() {
	b := 23
	x := 1 << b  
	println(x)
}

位清除 (AND NOT, bit clear)和 异或 (XOR)不同。
清除将左右操作数对应二进制位都为 1 的重置为 0(类似位图),以达到一次清除多个标记位的目的。

0101 & 0011 = 0001  // AND   与:都为 1
0101 | 0011 = 0111  // OR    或:至少一个 1
0101 ^ 0011 = 0110  // XOR   异或:只有一个 1
      ^0111 = 1000  // NOT   取反 (一元)
func main() {
	a := 0b01100101
	b := 0b11010100
	
	x := a ^ b   // 10110001
	c := a &^ b  // 00100001
    
	fmt.Printf("%08b\n", x)
	fmt.Printf("%08b\n", c)
}
const (
	read    byte = 1 << iota
	write
	exec
	freeze
)

func main() {
	a := read | write | freeze
	b := read | exec
    
	c := a &^ b 
    
	println(c == write | freeze) // true
	println(c & write == write)  // true
	println(c & read == read)    // fasle
}

初始化

对复合类型(数组、切片、字典、结构体)变量初始化时,有一些语法限制。

  • 初始化表达式须含类型标签。(数组、字典元素可省略)
  • 左大括号不能另起一行。
  • 多个成员初始值以逗号分隔。
  • 允许多行,但每行须以逗号或右大括号结束。
type data struct {
	x int
	s string
}

func main() {
	var a data = data{1, "abc"}
	       a2 := data{1, "abc"}
	          // ~~~~

	b := data {  // <---
		1,   
		"abc",   // <---
	}

	c := []int{
		1,
		2 }      // <---

	d := []int{1, 2,
		3, 4,
		5,       // <---
	}
}

作用域

通常意义上的作用域由大括号构成。作用域构成独立空间,内部所定义成员无法被外部访问。
当然,也有更大范围的作用域,如包(package),它有自己的规则。

  • 同级作用域相互隔离。
  • 下层可访问上层作用域成员。
  • 下层作用域遮蔽上层作用域同名成员。
func main() {
	x := 1

	{
		x := "abc"     // 新变量,遮蔽。
		y := 2
		println(x, y)  // abc, 2
	}

	println(x)         // 1
	println(y)         // undefined: y
}

作用域限定变量可被谁访问,而生命周期表示对象存活时间(可被不同作用域引用),不同混同。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文