go语言学习笔记(五)——代码块和变量重名

  • 前言

       代码块和作用域:作用域简单来说就是变量作用的范围,变量在哪些函数哪些范围可以使用,而在其他部分不可以,要用得重新定义。一个程序实体的作用域总是会被限制在某个代码块中,而这个作用域最大的用处就是对程序实体的访问权限的控制。对”高内聚,低耦合“这种程序设计思想的实践恰恰可以从这里开始

  • 如果一个变量与其外层代码块中的变量重名会出现什么状况

下面的命令源码文件有四个代码块,它们是:全域代码块,main包代表的代码块,main函数代表的代码块,在main函数中的一个用花括号包起来的代码块

package main

import "fmt"

var block = "package"

func main() {
	block := "function"
	{
		block := "inner"
		fmt.Printf("The block is %s.\n", block)
	}
	fmt.Printf("The block is %s.\n", block)
}

那么代码能通过编译吗,答案是肯定能的,运行后打印出的内容是:

The block is inner
The block is function

对于不同的代码块来说,其中的变量重名没什么大不了,照样可以通过编译 ,即便这些代码块有着直接的嵌套关系也是如此

 这样规定方便且合理,但同时也引来另一个问题:我们引用变量的时候到底用的是哪一个?

先来看一下go语言中查找变量的过程(同样适用于任何程序实体)

     1.代码引用变量时总会最优先查找当前代码块中(不包含任何子代码块)的那个变量

     2.如果当前代码块中没有声明以此为名的变量,那么程序会沿着代码块的嵌套关系,一层一层的查找

     3.一般情况下,程序会一直查到当前代码包代表的那层代码块。如果仍然找不到,那么go语言的编译器就会报错了

再考虑是否会从导入的其他包中查找

     1.如果我们导入了其他包,那么引用其中的程序实体时需要以限定符为前缀的。所以程序在找代表变量的那个未加限定符的名字的时候,是不会去被导入的那些代码包查找的

     2.有个特殊情况,如果把导入包写成import  .XXX的形式(注意中间的那个“.”),那么就会让这个“XXX"包中公开的程序实体被当前源码文件的代码视为当前代码包中的程序实体(比如代码包中有import  .fmt,那么我们在引用fmt.Printf函数的时候直接用Printf)

明白上述过程后再看示例,在示例中,main函数中的block变量屏蔽了全域的block(package),在main函数中的inner block,又不会影响main函数中用短变量定义的变量block。而在导入包中也不存在import .XXX形式,自然也无需考虑会从导入包查找block变量。

  • 不同代码块中的重名变量与变量重声明区别到底在哪

1.重声明的变量一定是同在某一个代码块内。而可重名变量指的正是在多个代码块之间的由相同的标识符代表的

2.重声明是对同一个变量的多次声明,变量只有一个。而可重名的变量是有多个的

3.重声明的变量类型必须始终一致的,而可重名变量的类型是可以任意的

4.可重名变量所在的代码块会屏蔽与它直接或者间接的子代码块的同名变量,这一情况在变量重声明场景下不会发生

 

  • 扩展:import的方式

除了一些import常用的几种方式,但是还有一些特殊的import,让很多新手很费解,下面我们来一一讲解一下
到底是怎么一回事

1. 点操作
我们有时候会看到如下的方式导入包
import(
. "fmt"
)
这个点操作的含义就是这个包导入之后在你调用这个包的函数时,你可以省略前缀的包名,也就是前面你调
用的fmt.Println("hello world")可以省略的写成Println("hello world")
2. 别名操作
别名操作顾名思义我们可以把包命名成另一个我们用起来容易记忆的名字
import(
f "fmt"
)
别名操作的话调用包函数时前缀变成了我们的前缀,即f.Println("hello world")
3. _操作
这个操作经常是让很多人费解的一个操作符,请看下面这个import
import (
"database/sql"
_ "github.com/ziutek/mymysql/godrv"
)
_操作其实是引入该包,而不直接使用包里面的函数,而是调用了该包里面的init函数。

  • 思考题

通过import .XXX这种方式导入的代码包中的变量与当前代码包中的变量重名了,那么Go语言是会把它们当作“可重名变量”看待还是报错呢?

答:会报redeclared。
采用import . xxx如文章所说,基本上就会认为引入的代码包的代码,如同在本包中一样,那作用域其实是同一个,自然不允许重复声明。

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你好!感谢提问。下面是有关 K210 学习笔记中串口通信的一些内容: 在 K210 开发板上,串口是一种常见的通信接口,用于将数据从一个设备传输到另一个设备。串口通信通常使用 UART (Universal Asynchronous Receiver/Transmitter) 协议。 要在 K210 上进行串口通信,首先需要使用两个引脚:一个用于接收数据(RX),一个用于发送数据(TX)。这些引脚可以通过 GPIO 端口与外部设备连接。 在 K210 的开发环境中,可以使用 MaixPy 或者 Kendryte Standalone SDK 进行串口编程。 在 MaixPy 中,可以使用 `uart` 模块来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```python from machine import UART uart = UART(UART.UART1, 115200) ``` 然后,可以使用 `uart.write()` 函数发送数据,使用 `uart.read()` 函数接收数据。例如: ```python uart.write("Hello, world!\n") data = uart.read(10) ``` 在 Kendryte Standalone SDK 中,可以使用 `uart.h` 头文件中的函数来进行串口通信。例如,要初始化一个串口对象并设置波特率为 115200,可以使用以下代码: ```c #include "uart.h" uart_init(UART_DEVICE_1, 115200); ``` 然后,可以使用 `uart_send_data()` 函数发送数据,使用 `uart_receive_data()` 函数接收数据。例如: ```c uart_send_data(UART_DEVICE_1, "Hello, world!\n", 14); char buffer[10]; uart_receive_data(UART_DEVICE_1, buffer, 10); ``` 以上是关于 K210 学习笔记中串口通信的简要介绍。如果你有更具体的问题,请随时提问!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值