每天一点Go语言——变量、常量、运算符解析

每天一点Go语言——变量、常量、运算符解析

前言

? 前面简单说过有关Go语言的基础语法及其数据类型,大致上了解了Go语言程序的组成,而本文将讲述近乎所有编程语言都涉及的变量、常量以及运算符相关内容。

一、变量

何为变量?

? 对该专业名词解释:计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。Go语言中的变量由字母、数字、下划线组成,首字母不可以为数字。耳熟能详了哈~

? 笔者的理解:我编写程序的时候需要使用一个值,并且我一直想要重复使用,而且有时候这个值会发生变化等等,所以我需要声明一个变量来被这个值赋之。

怎么声明变量?

变量声明一般格式:

var 变量名 变量类型

var:变量声明关键字,表示声明变量

其次是变量的名字,最后是变量的类型(如int)

当然也有其他的变化格式,我们直接看实例:

实例1.1——变量格式写法1

package main
var a1 int = 10
var a2 = "hello world"
var b1 = 11
var b2 string = "你好,世界"
//c1 := 12 //这种不带声明格式的只能在函数体中出现,否则会报错:non-declaration statement outside function body
var c2 bool

func main(){
        println(a1,a2,b1,b2,c2)
        c1 := 12 //这种变量声明要注意:c1变量没有被提前声明过才可以这样赋值
        println(c1)
}

运行结果:

10 hello world 11 你好,世界 false
12

当然变量也可以一起声明,程序执行时会自动推断变量类型(与Python相像)

实例1.2——变量格式写法2

package main
//写法一:
var v1, v2, v3 int
//写法二:
var v11, v22, v33 = 4, 5, "hello"
//写法三:(需写在全局变量中,不可以写在函数体内部)
var (
        vv1 int
        vv2 bool = true
)
func main(){
        v1, v2, v3 = 1, 2, 3
        println(v1,v2,v3)
        println(v11,v22,v33)
        println(vv1,vv2)
}

运行结果:

1 2 3
4 5 hello
0 true

补充说明:

? 在变量的初始化时省略变量的类型而由系统自动推断,声明语句写上 var 关键字其实是显得有些多余了,因此我们可以将它们简写为 a := 50 或 b := false。 编译器对此会自动推断a为int类型,b为bool类型。

? 这种简短形式的变量声明需要注意以下事项:

  • 只能被用在函数体内部;
  • 相同的代码块中,不可以如此重复声明变量;

? 另外,变量需要先声明后使用(所有方式都一样);当声明了局部变量(函数体内部),而未使用,也会编译出错;但是全局变量可以不使用。

值类型与引用类型

值类型

? int、float、bool、string这些基本类型都属于值类型。值类型的典型特征就是:我们所赋值的操作在计算机中存储和使用的过程是这样的(先做了解即可):

? 定义变量到内存中,值类型的变量存储在栈中,赋值,是将该值进行了一个拷贝再将这个拷贝的内容赋予给变量,变量(值类型)与拷贝的值之间的关系:变量直接指向内存中的值。

? 可以通过&变量名获取变量的内存地址,每次获取的地址可能不一样。

实例1.3——值类型变量内存地址

package main

var a int = 10

func main(){
    println(a)
    println(&a)
}

运行结果:

10
0x4a4018

引用类型(先作了解)

? Go语言中的引用类型有:映射(map)、数组切片(slice)、通道(channel)、方法和函数。

? Go语言存在垃圾回收器,因此在一个本地变量不再被使用时就会被回收掉,此时本地变量的生命周期由它们的作用域决定。对于管理本地变量的生命周期,我们需要用到指针,使用指针就可以使得对应变量的生命周期独立与作用域。

? 使用指针能控制变量的生命周期,不受作用域的影响,另外变量在传递过程中使成本最小化,并且可以修改变量的内容,而不是对复制的值进行操作。当然,指针也是一个变量,表示的是存放(保存了)另一个变量的内存地址,任何被指针保存的内存地址的变量都可以通过指针来修改内容。

&和*理解:
  • 操作符& : 当作二元操作符时,是按位与操作;当作一元操作符时,是返回该变量的内存地址
  • 操作符* : 当作二元操作符时,是相乘的操作;当作一元操作符(解引用操作符)时,是返回该指针指向的变量的值,其实就是解除变量的指针引用,返回该变量的值。

实例1.4——指针的创建与使用

package main
import "fmt"

func main(){
    a := 3
    p := &a //获取变量a的内存地址,并且将其赋值给p
    fmt.Printf("a的值为: %v,a的指针为: %v,p指向的变量的值为: %v\n",a,p,*p)
}

运行结果:

~~~a的值为: 3,a的指针为: 0xc4200160d8,p指向的变量的值为: 3


?   也就是说*p和a的值是相等的,可以交换使用。两者都与同一块内存地址相关联,任意一个变量进行修改操作都会影响到另一个变量的值,但是若变量p被赋值其他变量的指针就不行了

### 空指针

?   当一个指针被定义后没有分配到任何变量,值就为nil,叫做空指针。nil在概念上和其它语言的null、None、nil、NULL一样,都指代零值或空值。

#### 实例1.5——空指针

~~~go
package main

import "fmt"
func main() {
   var  ptr *int
   fmt.Printf("ptr 的值为 : %x\n", ptr  )
}

~~~运行结果:ptr 的值为 : 0


# 二、常量

?   Go语言常量就是值的标识符,程序运行时,不会被修改。常量中的数据类型只可以是bool型、数字型和字符串型。

常量定义格式:

~~~go
const identifier [type] = value

解释:const ——关键字 ,表示该变量将定义为常量不可更改

实例2.1——常量定义与使用

package main

import "fmt"
const m string = "hello" //显式类型定义
const n = "world" //隐式类型定义

func main() {
    const LENGTH int = 10
    const WIDTH int = 5
    var area int
    const a, b, c = 1, false, "str" //多重赋值

    area = LENGTH * WIDTH
    fmt.Printf("面积为 : %d\n", area)
    println(m, n)
    println(a, b, c)
    //m = "wrong" //错误示范
    //println(m) //编译报错:cannot assign to m,说明const变量不可以更改
}

运行结果:

面积为 : 50
hello world
1 false str

当然,常量也可用作枚举

const (
    Yes = 0
    No = 1
    Notsure = 2
)

iota

? iota,一个特殊常量,可以认为是一个能够被编译器修改的常量

实例2.2——iota

package main

import "fmt"

func main() {
    const (
            a = iota   //0
            b          //1
            c          //2
            d = "ha"   //独立值,iota += 1
            e          //"ha"   iota += 1
            f = 100    //iota +=1
            g          //100  iota +=1
            h = iota   //7,恢复计数
            i          //8
    )
    fmt.Println(a,b,c,d,e,f,g,h,i)
}

运行结果

~~~0 1 2 ha ha 100 100 7 8


从给出结果的现象可以知道:

1、在go语言编程中,iota是一个会在程序运行过程中自动变换的常量;

2、在给const修饰的变量赋值时,每次会隐藏性自增1,无论是不是在赋予给定的值;

3、当赋予给定的值给变量后,该变量之后的变量又未赋予其他的给定的值时,其后面的变量的值和该变量相等;就如上面的d和e,f和g ;但是有例外(看下面的例子)

4、而当变量回归赋值iota时,将按照自增的结果赋值给变量。

如下面的例子:

#### 实例2.3——有趣的iota

~~~go
package main

import "fmt"
const (
    i=1<<iota   //"<<"——此符号表示的位运算符,左移;此时对应关系为i——>1<<iota:1左移0位;则i的值为1
    j=3<<iota   //此时对应关系为:j——>3<<iota为3,iota的值为1,则左移1位,即0011——>0110=6
    k           //但是此时关系为k——>3<<iota,而不是6<<2,iota为2,k的值为12
    l
    m=iota
)
func main() {
    fmt.Println("i=",i)
    fmt.Println("j=",j)
    fmt.Println("k=",k)
    fmt.Println("l=",l)
    fmt.Println("m=",m)
} 

运行结果:

i= 1
j= 6
k= 12
l= 24
m= 4

三、运算符

? 近乎所有的程序语言都有运算符,运算符的作用无外乎两个:数学运算和逻辑运算

Go语言内置的运算符有:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符

1、算数运算符

? 包括:+、-、*、/、%、++、-- 后三个表示取余,自增,自减

实例3.1——算法运算符演示

package main

import "fmt"

func main() {

   var a int = 21
   var b int = 10
   var c int

   c = a + b
   fmt.Printf("加法:  c 的值为 %d\n", c )
   c = a - b
   fmt.Printf("减法:  c 的值为 %d\n", c )
   c = a * b
   fmt.Printf("乘法:  c 的值为 %d\n", c )
   c = a / b
   fmt.Printf("除法:  c 的值为 %d\n", c )
   c = a % b
   fmt.Printf("取余:  c 的值为 %d\n", c )
   a++
   fmt.Printf("a自增:   值为 %d\n", a )
   a--
   fmt.Printf("a自减:   值为 %d\n", a )
}

运行结果:

加法:  c 的值为 31
减法:  c 的值为 11
乘法:  c 的值为 210
除法:  c 的值为 2
取余:  c 的值为 1
a自增:   值为 22
a自减:   值为 21

2、关系运算符

包括 == 、!=、>、<、 >=、 <= 分别对应:判断是否等于,是否不等于,大于,小于,大于等于,小于等于

? 本文对此不做代码演示了,因为涉及到控制流程语句下一篇会讲

3、逻辑运算符

? 下图表列出了所有Go语言的逻辑运算符。假定 A 值为 True,B 值为 False。

4、位运算符

? 位运算符的作用是对整数在内存中的二进制位进行操作。

下表列出了位运算符 &, |, 和 ^ 的计算:表示逻辑上的“与或非”的关系

总结:

&:两边为真才为真

|:两边为假才为假

^:两边不同才为真

当然还有上述的左移、右移计算。举例说明:

60&13的结果为:12,计算方法是60和13转换为二进制做按位与运算,即:0011 1100 & 0000 1101= 0000 1100

60|13的结果为:61,计算方法是60和13转换为二进制做按位或运算,即:0011 1100 | 0000 1101= 0011 1101

5、赋值运算符

赋值运算符如下:

6、其他运算符

主要就是上面所提到的&和*,分别表示为返回变量存储地址和指针变量

运算符优先级

有些运算符拥有较高的优先级,二元运算符的运算方向均是从左至右。下表列出了所有运算符以及它们的优先级,由上至下代表优先级由高到低:(推荐编程的时候使用括号提升优先级,也是为了增强代码的可读性)

四、总结

? 本文讲述了go语言中有关变量、常量、运算符的内容。变量中注意定义变量的格式与位置,尤其是简明格式,其次是常量,需要留意一个特殊常量iota。最后则是运算符,需要在实际编程的案例中使用才能体会感悟。

原文地址:https://blog.51cto.com/14557673/2484879

时间: 2024-11-09 02:57:45

每天一点Go语言——变量、常量、运算符解析的相关文章

浅谈C语言变量声明的解析

C语言本身提供了一种不甚明确的变量声明方式--基于使用的声明,如int *a,本质上是声明了*a的类型为int,所以得到了a的类型为指向int的指针.对于简单类型,这样声明并不会对代码产生多大的阅读障碍,而对于复杂的声明,比如标准库的signal函数签名,void (*signal( int sig, void (*handler) (int))) (int),这是什么?一眼看不出来吧,这是一个函数,接受两个参数,一个int,一个函数指针,而这个函数指针指向的函数接受一个int并返回void:返

C语言---程序的一般形式、数据类型、常量变量、运算符、表达式、格式化输入输出

1. 程序的一般形式 (1)注释 ① 分类:单行注释( // ): 注释一行.多行注释( /**/ ): 在这个区间内,都属于多行注释,可以换行. ② 作用:提示代码的作用,提示思路   不写注释的后果:出来混总是要还的. ③ 单行注释不能换行 (2) #include  #import ① 导入文件,系统提供类库文件中包含一些功能函数,如果想在某个文件中使用,必须导入需要的文件. ② stdio  标准输入输出  standard input output (3) main  函数,又称主函数

JAVA之旅(一)——基本常识,JAVA概念,开发工具,关键字/标识符,变量/常量,进制/进制转换,运算符,三元运算

JAVA之旅(一)--基本常识,JAVA概念,开发工具,关键字/标识符,变量/常量,进制/进制转换,运算符,三元运算 Android老鸟重新学一遍JAVA是什么感觉?枯燥啊,乏味啊,而且归纳写博客,都是很痛苦的事情,但是程序之路这么长,你必须精通的不能再精通一门语言才行(有点说大了哈),但是最起码你要如鱼得水吧,我准备的资料有: JAVA编程思想 深入浅出JAVA 黑马,传智,慕课,极客学院等-的视频 Google搜索 我们既然是重新学一遍,那我们尽量就是用记事本去敲代码好了,这里我用notep

黑马程序员——Java基础语法(一) --- 关键字、标识符、注释、常量和变量、运算符

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 本篇博文主要总结java的基础语法,主要的内容包括:关键字.标识符.注释.常量和变量.运算符几部分. 一.关键字 关键字是被Java语言赋予了特殊含义的单词.关键字中所有的字母都是小写. java中的关键字主要包括如下几部分: 1.用于定

Go语言之常量与运算符

用例1 //此文件用来练习 //常量与运算符的 package main import "fmt" //定义单个常量 const SPARK_NAME = "spark-test001" const NODE_NUM int = 3 //下面的方式,只是简写 const ( CPU = 3.4 MEMORY = 1024 ) //同时定义多个变量 const FTP_NAME, ES_NAME, YARN_NAME = "ftp-beijing"

c#笔记(一)——常量,变量,运算符

注释,单行,多行,注释函数 定义变量, 交换两个int变量的值(int a,int b) /int c;c=a;a=b:b=c; /a=a+b;b=a-b;a=a-b; 变量命名规则: 1.相同变量名不能重复定义 2.只能包含数字,字母,下划线,并且数字不能开头 3.区分大小写,num,Num 4.不能使用关键字 5.见名知义 6.骆驼命名法,如果变量名只有一个单词,则该单词全部小写,如果有两个以上单词,从第二个单词开始每个单词首字母大写 [email protected]符号只能放在最前面,并

黑马程序员——01.Java编程基础(一) ——常量、变量、运算符

一.Java的基础组成 1.关键字--被赋予特殊含义的单词 ????????????学习Java的过程中去记忆. 2.标识符---就是指名称(类名.对象名.变量名.函数名.对象名等) ? ? ? ?????????1.26?个英文字母的大小写.0~9数字._和$(不允许有空格) ? ? ? ? ????????2.数字不能开头,关键字不能用来命名 ? ? ? ?????????3.类名-首字母大写(XxxYyyZzz);函数名-(xxxYyyZzz);变量名对象名(xxxyyyzzz) (1)和

01.Java编程基础(一) ——常量、变量、运算符

一.Java的基础组成 1.关键字--被赋予特殊含义的单词 ????????????学习Java的过程中去记忆. 2.标识符---就是指名称(类名.对象名.变量名.函数名.对象名等) ? ? ? ?????????1.26?个英文字母的大小写.0~9数字._和$(不允许有空格) ? ? ? ? ????????2.数字不能开头,关键字不能用来命名 ? ? ? ?????????3.类名-首字母大写(XxxYyyZzz);函数名-(xxxYyyZzz);变量名对象名(xxxyyyzzz) (1)和

Java基础语法(一)---关键字、常量、变量、运算符

Java基础语法(一)---关键字.常量.变量.运算符一.关键字 定义:被Java赋予了特殊含义的单词. 特点:体现上都是英文小写. 1. 用于定义数据类型的关键字 基本数据类型: 整数类型: byte(1字节,最大值127) short(2字节,最大值为2^15-1) int(4字节,最大值为2^31-1) long(8字节,最大值为2^63-1) 浮点类型: float (单精度实数在内存中占32bit 有效数字为6~7位) double(双精度实数占内存单元为64bit 有效数字为15~1