文档章节

Golang学习系列第二天:变量、常量、数据类型和流程语句

董广明
 董广明
发布于 07/13 23:41
字数 3542
阅读 74
收藏 0

「深度学习福利」大神带你进阶工程师,立即查看>>>

 

继golang第一天后,今天学习下golang的变量、常量、数据类型和控制流语句。

做过其他编程语言(比如JavaScript,java,python)项目的话,其实很好理解变量、常量、数据类型和控制流。

变量也被称为“变数”,是反映事物运动变化状态的量,比如汇率、房贷利率、贷款利率。

常量也被称“常数”,是反映事物相对静止状态的量,一旦定义,后续不能更改,比如圆周率PI。

Golang是不同于JavaScript和python,但它和java一样,是一种静态类型的编程语言,就是说定义变量或常量前需要声明其类型,

1.   变量

1.1  声明一个变量

变量在使用前需要声明,例如

package main

import "fmt"

func main() {
   var age int //age默认是0
   fmt.Printf("我的年龄是:%d 岁\n", age)
   age = 99 //给age赋值
   fmt.Printf("我的年龄是:%d 岁", age)
}

输出如图

1.2  自动推导变量类型

也可以用另一种写法,根据值推导变量的类型

package main

import "fmt"

func main() {
   var age = 99
   fmt.Printf("我的年龄是:%d 岁\n", age)
   age = 100  //
}

输出结果

1.3   速记法定义变量

还有一种更简洁的写法


import "fmt"

func main() {
   //fmt.Printf("hello, world\n")
   //var name string
   age := 99
   fmt.Printf("我的年龄是:%d 岁\n", age)
   age = 100
}

1.4  定义多个变量

真正开发时我们需要定义多个变量,比如一个用户有姓名,年龄,性别,地址,城市等多个字段

我是用1.1的写法定义变量的

package main

import "fmt"

func main() {
   //fmt.Printf("hello, world\n")
   //var name string
   var (
	name     string = "董广明"
	age      int    =  99
	city     string = "金陵城"
    )
    
   	fmt.Printf("我叫:%s ,年龄:(%d),所在城市:%s", name, age, city)
}

输出结果

1.5  函数式变量

JavaScript中这种定义很常见,一个变量可以是任何类型,包括函数,golang也支持,真是融合了好几种语言的特性,java并不支持

package main

import "fmt"

func main() {
   	//变量也可以是函数定义
   	print := func() {
		var (
	     name     string = "董广明,dgm"
         age      int    =  99
    	 city     string = "金陵其实就是南京"
         )
    
       	fmt.Printf("我叫:%s ,年龄:(%d),所在城市:%s", name, age, city)
	}
	
	print()
}

输出结果

 

2   常量

常量定义和变量类似,只是多了个关键字const

package main

import "fmt"

const (
	Pi    = 3.141592653
	Loading = false
	Name   = "dongguangming"
	Age = 99
)

func main() {
	const City = "金陵城"
	fmt.Println(City)
	fmt.Println(Pi)
	fmt.Println(Loading)
	fmt.Println(Name)
    fmt.Println(Age)
	//const CompanyName := "某公司"  //不支持, 编译不过去
}

输出结果

常量小结:Constants can only be character, string, boolean, or numeric values and cannot be declared using the := syntax. An untyped constant takes the type needed by its context.

 

3.   数据类型

分两种:基本数据类型和derived派生数据类型,在此只先介绍基本的数据类型,后一种以后单独介绍

3.1   基本数据类型

基本数据类型又有以下几种类型:布尔bool,字符串string,数值型number,复数型数据类型

3.1.1  布尔bool

bool类型表示布尔逻辑,它的值要么为true,要么为false

package main

import "fmt"

func main() {  
    have := true
    nohave := false
    fmt.Println("have:", have, "nohave:", nohave)
    result_and := have && nohave
    fmt.Println("result_and:", result_and)
    result_or := have || nohave
    fmt.Println("result_or:", result_or)
}

以上代码中,定义了 变量have并赋值为true和变量nohave并赋值为false

变量result_and被赋值为false,因为逻辑操作符&&表示两边的值都为true的情况下才返回ture,例子中只有have为true,故运算结果为false。

变量result_or被赋值为true,因为逻辑操作符||表示两边的值只要有一个为true的情况下就返回ture了,例子中刚好有have为true,故运算结果为true。

执行以上输出以下结果

理论分析是正确的

 

3.1.2  字符串String类型

字符串是字节的集合,存储了字符序列。

package main

import (  
    "fmt"
)

func main() {  
    first := "董"
    last := "广明"
    name := first + last
    fmt.Println("我的名字叫: ",name)
}

输出结果:

 

3.1.3  数值型

数值型细分有以下几种

Numeric types:

uint        either 32 or 64 bits,represents 32 or 64 bit unsigned integers depending on the underlying platform,32 bits in 32 bit systems and 64 bits in 64 bit systems( 0 to 4294967295 in 32 bit systems and 0 to 18446744073709551615 in 64 bit systems ).
int         either 32 or 64 bits,represents 32 or 64 bit integers depending on the underlying platform. You should generally be using int to represent integers unless there is a need to use a specific sized integer,32 bits in 32 bit systems and 64 bit in 64 bit systems(-2147483648 to 2147483647 in 32 bit systems and -9223372036854775808 to 9223372036854775807 in 64 bit systems)
uintptr     an unsigned integer large enough to store the uninterpreted bits of
            a pointer value
uint8       the set of all unsigned  8-bit integers (0 to 255)
uint16      the set of all unsigned 16-bit integers (0 to 65535)
uint32      the set of all unsigned 32-bit integers (0 to 4294967295)
uint64      the set of all unsigned 64-bit integers (0 to 18446744073709551615)

int8        the set of all signed  8-bit integers (-128 to 127)
int16       the set of all signed 16-bit integers (-32768 to 32767)
int32       the set of all signed 32-bit integers (-2147483648 to 2147483647)
int64       the set of all signed 64-bit integers
            (-9223372036854775808 to 9223372036854775807)

float32     the set of all IEEE-754 32-bit floating-point numbers
float64     the set of all IEEE-754 64-bit floating-point numbers

complex64   the set of all complex numbers with float32 real and imaginary parts
complex128  the set of all complex numbers with float64 real and imaginary parts

byte        alias for uint8
rune        alias for int32 (represents a Unicode code point)

整数式

package main

import (  
    "fmt"
    "unsafe"
)

func main() {  
    var first int = 88
    second := 99
    fmt.Println("第一个值=", first, ",第二个值=", second)
    fmt.Printf("first的类型是:%T, first的大小 %d", first, unsafe.Sizeof(first)) //type and size of first
    fmt.Printf("\nsecond的类型是: %T, second的大小 %d", second, unsafe.Sizeof(second)) //type and size of second
}

浮点数

package main

import (  
    "fmt"
)

func main() {  
    first, second := 6.66, 9.99
    fmt.Printf("first的类型是 %T second的类型是%T\n", first, second)
    sum := first + second
    diff := first - second
    fmt.Println("相加和是", sum, "相减差是", diff)
}

 复数计算

package main

import (  
    "fmt"
)

func main() {  
    first := complex(5, 7)
    second := 8 + 27i
    sum := first + second
    fmt.Println("复数相加和:", sum)
    diff := first - second
    fmt.Println("复数相减差:", diff)
    product := first * second
    fmt.Println("复数相乘:", product)
}

 

由于数值型可能会参数数学计算,但golang本身没有自动转换功能,故需要手工显示转换数据类型

package main

import (  
    "fmt"
)

func main() {  
    first := 66      //int
    second := 77.7    //float64
    //sum := first + second //int + float64 not allowed,编译不通过,故需要下面显示转换,golang没有自动转换功能
    sum := first + int(second) //second is converted to int

    fmt.Println(sum)
}

但是有例外情况

package main

import (  
    "fmt"
)

func main() {  
    first := 10
    var second float64 = float64(first) //this statement will not work without explicit conversion
    fmt.Println("second:", second)
}

输出结果

没有像其他语言转换后有标志10.0f 

 

4. 流程语句

分三种:if条件/if else, loop循环,switch 

4.1  if, if else

4.1.1   if语句

用于指定是否应执行相应的代码块,语法结构:

if(condition) {
  // 执行condition为true时的代码逻辑
}

例如

package main
import "fmt"

func main() {
    var country = "中国"
	var age = 18
	if(country == "中国" && age>=18) {
		fmt.Printf("你已经是成年人了,该挣钱了\n")
	}
}

输出结果

Note that, You can omit the parentheses () from an if statement in Golang, but the curly braces {} are mandatory - 

注意,在golang的世界里你可以不使用if后面的插入语(),但是后面的花括号是必须的,示例

if country == "中国" && age>=18 {
		fmt.Printf("你已经是成年人了,该挣钱了\n")
}

4.1.2  If-Else语句

一个if语句能配合else语句块使用,当if里的条件为false,else语句块的逻辑代码会被执行,代码结构

if condition {
  // code to be executed if the condition is true
} else {
  // code to be executed if the condition is false
}

示例代码

package main
import "fmt"

func main() {
	var age = 18
	if age >= 18 {
		fmt.Println("很好,你已经是个成年人了,不是小孩子了!!!")
	} else {
		fmt.Println("抱歉,你还未成年!")
	}
}

输出结果

4.1.3   If-Else-If链

if语句能够有多个else语句块,例如

package main
import "fmt"

func main() {
	var age = 12
	if age>=6 && age < 11 {
		fmt.Println("你可能在上小学");
	} else if age >= 12 && age < 15 {
		fmt.Println("你可能在上初中");
	} else if age >= 15 && age < 18 {
		fmt.Println("你可能在上高中")
	} else {
		fmt.Println("上大学了")
	}
}

4.1.4  if短语句

if语句允许在条件表达式之前包含一个简短的声明语句

package main
import "fmt"

func main() {
   if first := 10; first%2 == 0 {
     fmt.Printf("%d 是偶数\n", first)
   } 

   if second := 15; second%2 == 0 {
  fmt.Printf("%d 是偶数\n", second)
} else {
  fmt.Printf("%d 是奇数\n", second)
}
}

特别留意: The variable declared in the short statement is only available inside the if block and it’s else or else-if branches ,

If you’re using a short statement, then you can’t use parentheses. 如下代码会报错

if (second := 15; second%2 == 0) { //语法错误不能有()
    fmt.Printf("%d 是偶数\n", second)
} else {
    fmt.Printf("%d 是奇数\n", second)
}

 

4.2   循环Loop

循环用于重复运行代码块,golang 只要一种循环语句l:the for loop,结构如下

for initialization; condition; increment {
  // 循环体
}

初始化语句initialization 在循环的第一次迭代之前执行一次。在每次迭代中,都会检查条件condition,如果条件的计算结果为true,则执行循环体,否则,循环终止。增量语句increment 在每次迭代结束时执行。示例代码:

package main
import "fmt"

func main() {
	for i := 0; i < 10; i++ {
		fmt.Printf("%d ", i)
	}
}

看,它不需要java一样需要插入语。

特别注意: for循环中的initialization和increment语句都是可选的,可以省略掉,如下

省略掉初始化语句

package main

import "fmt"

func main() {
	i := 2
	for ; i <= 10; i += 2 {
		fmt.Printf("%d ", i)
	}
}

省略掉增量语句

package main

import "fmt"

func main() {
	i := 2
	for i <= 20 {
		fmt.Printf("%d ", i)
		i *= 2
	}
}

最后,您还可以从Golang中的for循环中省略该条件,这将给你一个无限循环

package main

func main() {
    for {
      //循环体语句
    }
}

 

终止break语句

您可以使用break语句在循环正常终止之前中断循环,比如

package main

import "fmt"

func main() {
	for num := 1; num <= 50; num++ {
		if num%4 == 0 && num%7 == 0 {
			fmt.Printf("终止循环的数: %d\n", num)
			break
		}
		fmt.Printf("未终止循环的数: %d\n", num)
	}
}

输出

 

continue语句

continue语句用于中途停止循环体的运行,并继续到循环的下一次迭代。 

package main
import "fmt"

func main() {
	for num := 1; num <= 10; num++ {
		if num%2 == 0 {
			continue;
		}
		fmt.Printf("%d \n", num)
	}
}

输出结果

 

无线循环infinite loop

语法结构如下

for {  
  //循环体
}
package main

import "fmt"

func main() {  
    for {
        fmt.Println("Hello World")
    }
}

4.3   Switch 

Switch语句接受一个表达式,并将其与可能的情况列表相匹配。一旦找到匹配项,它将执行匹配大小写中指定的代码块。

示例代码

package main

import (  
    "fmt"
)

func main() {  
    age := 8
    switch age {
    case 8:
        fmt.Println("小学生")
    case 13:
        fmt.Println("初中生")
    case 17:
        fmt.Println("高中生")
    case 19:
        fmt.Println("大学生")
    case 21:
        fmt.Println("社会人士")
    default: //default case
        fmt.Println("小朋友")
    }
}

特别注意:

Go从上到下逐一评估所有开关案例,直到案例成功为止。 案例成功后,它将运行该案例中指定的代码块,然后停止(不评估其他任何案例)。

这与其他语言(例如C,C ++和Java)相反,在C,C ++和Java中,您明确需要在每个案例的主体之后插入break语句以停止对后续案例的评估。

如果没有任何一种情况成功,则执行默认情况。

 

4.3.1 Switch和简短的语句

就像if一样,switch也可以在条件表达式之前包含一个简短的声明语句。 如下

package main

import (
	"fmt"
)

func main() {
	switch dayOfWeek := 6; dayOfWeek {
	case 1:
		fmt.Println("星期一")
	case 2:
		fmt.Println("星期二")
	case 3:
		fmt.Println("星期三")
	case 4:
		fmt.Println("星期四")
	case 5:
		fmt.Println("星期五")
	case 6:
		{
			fmt.Println("星期六")
			fmt.Println("周末了哈哈哈!")
		}
	case 7:
		{
			fmt.Println("星期天")
			fmt.Println("周末了哈哈哈!")
		}
	default:
		fmt.Println("世界末日")
	}
}

注意: 唯一的区别是,由简短语句声明的变量仅在switch块内部可用。

 

4.3.2 case情况下多表达式

通过用逗号将多个表达式分隔开,可以包含多个表达式。

package main

import (  
    "fmt"
)

func main() {  
    dayOfWeek  := "2"
    switch dayOfWeek {
    case "1", "2", "3", "4", "5": //multiple expressions in case
        fmt.Println("上班日")
    default:
        fmt.Println("休息日")
    }
}

4.3.3 没有表达式的switch

开关中的表达式是可选的,可以省略。 如果省略该表达式,则认为该开关为true,并且评估每个case表达式的真性并执行相应的代码块。

package main

import (  
    "fmt"
)

func main() {  
    num := 75
    switch { // expression is omitted
    case num >= 0 && num <= 50:
        fmt.Println("大于等于0且小于等于50")
    case num >= 51 && num <= 100:
        fmt.Println("大于等于50且小于等于100")
    case num >= 101:
        fmt.Println("大于100")
    }
}

 

4.3.4类型type switch

switch也可以用来发现接口变量的动态类型。 这种类型开关使用括号内带有关键字type的类型断言的语法

如果switch在表达式中声明了变量,则该变量在每个子句中将具有相应的类型。 在这种情况下重用名称也是惯用的,实际上是在每种情况下声明一个具有相同名称但类型不同的新变量。

示例代码有趣

package main

import (
	"fmt"
)

func main() {
	var t interface{}
	t = 10
	
	switch t := t.(type) {
	default:
		fmt.Printf("unexpected type %T\n", t) // %T prints whatever type t has
	case bool:
		fmt.Printf("boolean %t\n", t) // t has type bool
	case int:
		fmt.Printf("integer %d\n", t) // t has type int
	case *bool:
		fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
	case *int:
		fmt.Printf("pointer to integer %d\n", *t) // t has type *int
	}
}

输出结果

 

4.3.5 组合多个switch case(结合上面的案例4.3.1和4.3.2)

代码如下

package main
import "fmt"

func main() {
	switch dayOfWeek := 5; dayOfWeek {
		case 1, 2, 3, 4, 5:
			fmt.Println("上班日")
		case 6, 7:
			fmt.Println("休息")
		default:
			fmt.Println("世界末日")		
	}
}

 

总结: 语言学的知识是相通的,用不到十一就能结束,语法不需要花太多时间学,就好比园区很多码农(java本身的知识点再加上spring生态圈里的知识点,并没有全部学完,甚至有的概念都不知道,其实并不影响干活),60%~80%的知识点就够普通开发了,golang更像是大杂烩,有C的味道,又有JavaScript的口感,看上去有时又像java!!!

 

参考:

  1.  What’s the Go language really good for?  https://www.infoworld.com/article/3198928/whats-the-go-language-really-good-for.html

  2. Golang for loop https://m.youtube.com/watch?feature=youtu.be&v=rO11gboBY3M&fbclid=IwAR0LS6yzU0DksIEkl8neo6pDT31WsmFUwCZoU77RYrcpvcEYhtO22zSCpOs

  3. Golang Cheatsheet: Variables https://ado.xyz/blog/golang-cheatsheet-variables/

  4. Default Values for Go Types https://ado.xyz/byte/default-values-for-golang-types/

  5. Programmering i Go  https://unixsheikh.com/programmering-i-go/

 

董广明
粉丝 22
博文 92
码字总数 138052
作品 0
南京
其他
私信 提问
加载中
请先登录后再评论。
Netty那点事(三)Channel与Pipeline

Channel是理解和使用Netty的核心。Channel的涉及内容较多,这里我使用由浅入深的介绍方法。在这篇文章中,我们主要介绍Channel部分中Pipeline实现机制。为了避免枯燥,借用一下《盗梦空间》的...

黄亿华
2013/11/24
2W
22
访问安全控制解决方案

本文是《轻量级 Java Web 框架架构设计》的系列博文。 今天想和大家简单的分享一下,在 Smart 中是如何做到访问安全控制的。也就是说,当没有登录或 Session 过期时所做的操作,会自动退回到...

黄勇
2013/11/03
3.7K
8
Flappy Bird(安卓版)逆向分析(一)

更改每过一关的增长分数 反编译的步骤就不介绍了,我们直接来看反编译得到的文件夹 方法1:在smali目录下,我们看到org/andengine/,可以知晓游戏是由andengine引擎开发的。打开/res/raw/at...

enimey
2014/03/04
6.2K
18
SQLServer实现split分割字符串到列

网上已有人实现sqlserver的split函数可将字符串分割成行,但是我们习惯了split返回数组或者列表,因此这里对其做一些改动,最终实现也许不尽如意,但是也能解决一些问题。 先贴上某大牛写的s...

cwalet
2014/05/21
9.7K
0
Swift百万线程攻破单例(Singleton)模式

一、不安全的单例实现 在上一篇文章我们给出了单例的设计模式,直接给出了线程安全的实现方法。单例的实现有多种方法,如下面: class SwiftSingleton { } 这段代码的实现,在shared中进行条...

一叶博客
2014/06/20
3.6K
16

没有更多内容

加载失败,请刷新页面

加载更多

【实用技巧】MAC苹果电脑怎么远程?

一般电脑远程包括三方面: 1、如果从外部windows或者linux终端连接到mac苹果电脑; 2、从苹果电脑内如何远程外面的windows、linux和mac等; 3、苹果和安卓手机怎么远程连接苹果/Windows电脑。...

osc_doeya1ck
56分钟前
22
0
虚拟主机和VPS主机有哪些不同点呢

虚拟主机是一种在单一主机或主机群上,实现多网域服务的方法,可以运行多个网站或服务的技术。vps主机是将一台服务器分割成多个虚拟专享服务器的服务。实现VPS的技术分为容器技术和虚拟机技术...

osc_b88oux8w
57分钟前
19
0
合理的使用MySQL乐观锁与悲观锁

针对 MySQL的乐观锁与悲观锁的使用,基本都是按照业务场景针对性使用的。针对每个业务场景,对应的使用锁。 但是两种锁无非都是解决并发所产生的问题。下面我们来看看如何合理的使用乐观锁与...

php开源社区
58分钟前
25
0
fusionpbx 中文 汉化

  自己以前有从事过呼叫中心的工作经验,然而由于自己是从事后端开发,对于前端界面的开发还是有些吃力,但是自己却又想自己搭建一套呼叫中心,所以购买了一台云服务器并克隆了FusionPBX的...

osc_ydeb2o99
59分钟前
12
0
关于大O表示法和小O表示法

上节课老师讲了一下各种表示法,当时没咋听懂,后来查了一些资料弄懂了,记录一下。 主要是从维基百科上看的。http://en.wikipedia.org/wiki/Big_O_notation 大O表示法: f(x) = O(g(x)) 表示...

osc_3mzamgkq
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部