一起学Golang系列(四)学习Go语言语法,这篇文章就够了!

简介: 前面已经了 Go 环境的配置和初学Go时,容易遇到的坑。我们知道Go语言和我们以前的Java或是C#哈时候很大差别的。所以在学习Go,首先必须要熟悉Go语言的基础语法。接下来就为初学者大致介绍下Go语言基础语法。

前面已经了 Go 环境的配置和初学Go时,容易遇到的坑。我们知道Go语言和我们以前的Java或是C#哈时候很大差别的。所以在学习Go,首先必须要熟悉Go语言的基础语法。接下来就为初学者大致介绍下Go语言基础语法。

 

一、Go 程序的基本结构

下面是一个Go 程序的基本结构,包含(包声明,引入包,函数等)

package main // 定义包名,package main表示一个可独立执行的程序,每个 Go 应用程序都包含一个名为 main 的包。
import "fmt" // 导入需要使用的包(的函数,或其他元素)
func main() { // 程序的入口函数。main 函数是每一个可执行程序所必须包含的,一般来说都是在启动后第一个执行的函数。
  fmt.Println("Hello, World!")
}

上面的示例,就是最基本的Go 程序,其中:

  • package 表示程序所在的包名。
  • import 表示导入需要使用的包。
  • main 为程序的入口函数。

需要注意的是:同一文件夹下,只能有一个man函数,否则会报错。


二、Go语言的数据类型

Go提供了int、bool等基本数据类型,也有array、slice、map等高级数据类型。下面就来介绍这些数据类型的用法。

1. 基本数据类型

Go提供的布尔(bool)、数值类型(int,float)和字符串类型(string)等基本数据类型。用法与其他语言类似。  

  • 布尔类型(bool),布尔型的值只可以是常量 true 或者 false。一个简单的例子:var b bool = true。
  • 数值类型,又可以分为整数类型、浮点类型、和复数类型。

    整数类型包括(byte,rune,int/uint,int8/uint8,int16/uint16,int32/uint32,int64/uint64)

    浮点类型包括(float32,float64)

    复数类型包括(complex64,complex128)

  • 字符串类型,Go的字符串是由单个字节连接起来的。使用UTF-8编码标识Unicode文本。

2. 高级数据类型

Go语言除了提供以上一些基本数据类型,为了方便开发者,也提供了array、slice、map等高级数据类型。

  • 数组(array)
  • 切片(slice)
  • 字典(map)
  • 通道(channel)
  • 函数(function)
  • 结构体(function)
  • 接口(interface)
  • 指针(*Xxx,Pointer,uintptr)

这些高级数据类型中,array和map与java中的作用比较类似。但是,slice、channel等是Go独有的。后面会详细介绍。


除此之外,如果按照底层结构划分可以分为值类型和引用类型。

  • 值类型包括(所有基本数据类型,数组,结构体)。
  • 引用类型包括(slice,map,channel,function,interface,指针)。


三、变量&常量

Go 语言的变量名由字母、数字、下划线组成,其中首个字母不能为数字,声明变量的一般形式是使用 var 关键字。例如:var name string

1.声明变量

a.指定变量类型,声明后若不赋值,使用默认值。

var name string
name = "李四"


b.根据值自行判定变量类型。

var name = "李四"

上面的示例,Go会根据值判定变量name 的数据类型为string。


c.简短形式,省略var

age := 10

在使用简略形式定义变量时,需要注意以下几点:

  • (:=)是使用变量的首选形式
  • (:=)只能被用在函数体内,而不可以用于全局变量的声明与赋值。
  • (:=)左侧的变量不应该是已经声明过的,否则会导致编译错误。

 

2.声明常量 

Go语言中,常量的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。使用const 关键字定义。例如:

const name string = "abc"

或者还可以简化的方式定义,与变量的声明类似。具体如下

const name = "abc"


我们知道常量的值是不能被修改的。但是,Go语言提供了iota关键字来定义这种可以被修改的常量。使用方式如下:

const (
    a = iota
    b = "weiz"
    c = 9
    d = iota
)

上面的示例中,使用const关键字定义了四个常量。iota在 const关键字中,默认为 0,const 中每新增一行常量声明将使 iota 加1。所以,a的值就为0,d的值为3。我们可以输出a、b、c、d四个常量的值。看看是否如此:

image.png


iota 看起来挺饶的,使用时只要注意一下几点,多写多用几次就熟悉了

  1. iota表示连续的,无类型的整数常量,
  2. 以const开始的常量声明语句为单位,
  3. 从0开始,每赋给一个常量就递增一次
  4. 一旦跨越以const开始的常量声明语句就归0


四、运算符

Go 语言提供的运算符有:算术运算符、关系运算符、逻辑运算符、位运算符、赋值运算符、其他运算符。接下来让我们来详细看看各个运算符的介绍。 

1. 算术运算符

算术运算符,包括:+,-,*,/,%,++,--

package main
import "fmt"
func main() {
  var a int = 20
  var b int = 10
  var c int
  c = a + b
  fmt.Printf("加法运算的值为 %d\n", c )
  c = a - b
  fmt.Printf("减法运算的值为 %d\n", c )
  c = a * b
  fmt.Printf("乘法运算的值为 %d\n", c )
  c = a / b
  fmt.Printf("除法运算的值为 %d\n", c )
  c = a % b
  fmt.Printf("求余运算的值为 %d\n", c )
  a++
  fmt.Printf("递增运算的值为 %d\n", a )
  a=20
  a--
  fmt.Printf("递减运算的值为 %d\n", a )
}


2. 关系运算符

关系运算符,返回True或False ,a == b ,包括:==,!=,>,<,>=,<=。

package main
import "fmt"
func main() {
  var a = 20
  var b = 10
  fmt.Printf("a == b : %t\n", a == b)
  fmt.Printf("a != b : %t\n", a != b)
  fmt.Printf("a > b : %t\n", a > b)
  fmt.Printf("a < b : %t\n", a < b)
  a = 5
  b = 20
  fmt.Printf("a <= b : %t\n", a <= b)
  fmt.Printf("a >= b : %t\n", a >= b)
}

3.逻辑运算符

逻辑运算符,返回True或False ,包括:&&,||,!。

package main
import "fmt"
func main() {
  var a bool = true
  var b bool = false
  fmt.Printf("a && b 结果: %t\n", a && b)
  fmt.Printf("a || b 结果: %t\n" ,a || b)
  fmt.Printf("!b 结果: %t\n" ,!b)
}


4.位运算符

逻辑运算符对整数在内存中的二进制位进行操作,包括: &,|,^,<<和>>。

package main
import (
  "fmt"
)
func main() {
  var a int = 2 /* 2  = 0000 0010 */
  var b int = 7 /* 7  = 0000 0111 */
  fmt.Printf("a & b 的值为 %d\n", a&b)
  fmt.Printf("a | b 的值为 %d\n", a|b)
  fmt.Printf("a ^ b 的值为 %d\n", a^b)
  fmt.Printf("a << 2 的值为 %d\n", a<<1)
  fmt.Printf("b >> 2 的值为 %d\n", b>>1)
}


5. 地址运算符

地址运算符用于返回变量存储地址和定义支持变量。包括:&和*

  • & : 返回变量存储地址 (&originalValue)
  • * :指针变量 (*pointerValue)

 

package main
import "fmt"
func main() {
  var a = 4
  var ptr *int
  /*  & 和 * 运算符 */
  ptr = &a     /* 'ptr' 包含了 'a' 变量的地址 */
  fmt.Printf("a 的值为  %d\n", a)
  fmt.Printf("*ptr 为 %d\n", *ptr)
}


6. 接收运算符

接收运算符用于接收通道的数据或者给将数据加入通道。例如:(intChan<-1, <-intChan)。这个后面讲到channel的时候会详细介绍。



五、函数

Go语言的核心就是函数,它是基本的代码块,用于实现各种业务逻辑。Go 语言标准库同样也提供了非常多的内置的函数。例如,len() 函数可以接受不同类型参数并返回该类型的长度。


我们知道,Java或是C#通过public、private 控制函数的可见。但是,Go语言没有public等关键字。它是通过首字母大小写的方式区分的。当函数、结构等标识符以一个大写字母开头,如:GetInfo,那么使用这种形式的标识符的对象就可以被外部包的代码所使用(像面向对象语言中的 public);标识符如果以小写字母开头,则对包外是不可见的,但是他们在整个包的内部是可见并且可用的(像面向对象语言中的 protected )。


1.函数声明

Go 语言函数定义格式如下:

func function_name( [parameter list] ) [return_types] {
   函数体
}

函数声明告诉调用者函数的名称,返回类型,和参数。函数定义解析:

  • func:Go语言关键字,声明该代码块为函数。
  • function_name:函数名称。
  • parameter list:参数列表,指定的是参数类型、顺序、及参数个数。参数是可选的。
  • return_types:返回类型,函数返回一列值。return_types 是该列值的数据类型。有些功能不需要返回值,这种情况下 return_types 不是必须的。
  • 函数体:函数定义的代码集合。

下面是一个具体的函数定义:

func add(a int,b int ) int{
  return a+b
}

上面的示例是简单的加法运算,传入两个int参数,返回计算的值。Go语言支持如果所有的参数类型一样,可以使用简单写法:func add(a,b int) int{。这正是Go语言设计者的初衷:最大可能的简化程序,使其更加优雅。


2.函数返回多个值

Go 语言支持函数返回多个值,即一个函数,同时返回多个返回值。这正是Go语言比其他语言优雅、方便的地方之一。

package main
import (
  "fmt"
  "strconv"
)
func convert(a string, b string) (int, int) {
  x, _ :=strconv.Atoi(a)
  y, _ :=strconv.Atoi(b)
  return x, y
}
func main() {
  a, b := convert("5", "2")
  fmt.Println(a, b)
}

上面的示例我们可以看看到。如果函数返回多个值,但是我们不需要该值时,可使用“_”代替。


最后

以上,就把Go语言的基本语法介绍完了。所谓磨刀不误砍柴工,Go语言的语法有些和java类似,但也有很多不一样的地方。希望大家还是能熟悉掌握这些基础知识,这样后面真正学起Go来才会得心应手。

相关文章
|
17小时前
|
缓存 测试技术 持续交付
Golang深入浅出之-Go语言中的持续集成与持续部署(CI/CD)
【5月更文挑战第5天】本文介绍了Go语言项目中的CI/CD实践,包括持续集成与持续部署的基础知识,常见问题及解决策略。测试覆盖不足、版本不一致和构建时间过长是主要问题,可通过全面测试、统一依赖管理和利用缓存优化。文中还提供了使用GitHub Actions进行自动化测试和部署的示例,强调了持续优化CI/CD流程以适应项目需求的重要性。
27 1
|
17小时前
|
Kubernetes Cloud Native Go
Golang深入浅出之-Go语言中的云原生开发:Kubernetes与Docker
【5月更文挑战第5天】本文探讨了Go语言在云原生开发中的应用,特别是在Kubernetes和Docker中的使用。Docker利用Go语言的性能和跨平台能力编写Dockerfile和构建镜像。Kubernetes,主要由Go语言编写,提供了方便的客户端库与集群交互。文章列举了Dockerfile编写、Kubernetes资源定义和服务发现的常见问题及解决方案,并给出了Go语言构建Docker镜像和与Kubernetes交互的代码示例。通过掌握这些技巧,开发者能更高效地进行云原生应用开发。
27 1
|
17小时前
|
负载均衡 监控 Go
Golang深入浅出之-Go语言中的服务网格(Service Mesh)原理与应用
【5月更文挑战第5天】服务网格是处理服务间通信的基础设施层,常由数据平面(代理,如Envoy)和控制平面(管理配置)组成。本文讨论了服务发现、负载均衡和追踪等常见问题及其解决方案,并展示了使用Go语言实现Envoy sidecar配置的例子,强调Go语言在构建服务网格中的优势。服务网格能提升微服务的管理和可观测性,正确应对问题能构建更健壮的分布式系统。
16 1
|
1天前
|
消息中间件 Go API
Golang深入浅出之-Go语言中的微服务架构设计与实践
【5月更文挑战第4天】本文探讨了Go语言在微服务架构中的应用,强调了单一职责、标准化API、服务自治和容错设计等原则。同时,指出了过度拆分、服务通信复杂性、数据一致性和部署复杂性等常见问题,并提出了DDD拆分、使用成熟框架、事件驱动和配置管理与CI/CD的解决方案。文中还提供了使用Gin构建HTTP服务和gRPC进行服务间通信的示例。
11 0
|
1天前
|
Prometheus 监控 Cloud Native
Golang深入浅出之-Go语言中的分布式追踪与监控系统集成
【5月更文挑战第4天】本文探讨了Go语言中分布式追踪与监控的重要性,包括追踪的三个核心组件和监控系统集成。常见问题有追踪数据丢失、性能开销和监控指标不当。解决策略涉及使用OpenTracing或OpenTelemetry协议、采样策略以及聚焦关键指标。文中提供了OpenTelemetry和Prometheus的Go代码示例,强调全面可观测性对微服务架构的意义,并提示选择合适工具和策略以确保系统稳定高效。
13 5
|
1天前
|
监控 算法 Go
Golang深入浅出之-Go语言中的服务熔断、降级与限流策略
【5月更文挑战第4天】本文探讨了分布式系统中保障稳定性的重要策略:服务熔断、降级和限流。服务熔断通过快速失败和暂停故障服务调用来保护系统;服务降级在压力大时提供有限功能以保持整体可用性;限流控制访问频率,防止过载。文中列举了常见问题、解决方案,并提供了Go语言实现示例。合理应用这些策略能增强系统韧性和可用性。
14 0
|
1天前
|
负载均衡 算法 Go
Golang深入浅出之-Go语言中的服务注册与发现机制
【5月更文挑战第4天】本文探讨了Go语言中服务注册与发现的关键原理和实践,包括服务注册、心跳机制、一致性问题和负载均衡策略。示例代码演示了使用Consul进行服务注册和客户端发现服务的实现。在实际应用中,需要解决心跳失效、注册信息一致性和服务负载均衡等问题,以确保微服务架构的稳定性和效率。
11 3
|
存储 IDE Java
go语言简单入门
go语言简单入门
139 0
|
缓存 搜索推荐 编译器
Go 语言入门很简单 -- 17. Go Package #私藏项目实操分享#
Go 语言入门很简单 -- 17. Go Package #私藏项目实操分享#
141 0
Go 语言入门很简单 -- 17. Go Package #私藏项目实操分享#
|
编译器 Shell 测试技术
Go 语言入门很简单--技巧和窍门(Tips and Tricks)
Go 语言入门很简单--技巧和窍门(Tips and Tricks)
154 0
Go 语言入门很简单--技巧和窍门(Tips and Tricks)