Go语言公开或未公开的标识符的基本概念

Go语言支持从包里公开或者隐藏标志符,通过这个特性,可以让用户按照自己的规则控制标识符的可见性。

Go语言中的可见性,是通过声明类型的大小写来进行区别的。

例如下面的代码

// Package counters provides alert counter support.
package counters type alertCounter int

这里 alertCounter 就是外部不可见的,

此时如果在main包中的main方法想要访问这个内部的类型,就会出现下面的问题:

func main() {
counter := counters.alertCounter()
fmt.Printf("Counter: %d\n", counter)
}

不能引用未公开的名字

cannot refer to unexported name counters.alertCounter

规则详细如下:

一个标识符的名字以小写字母开头时,这个标识符就是未公开的,即包外的代码不可见。

一个标识符的名字以大写字母开头时,这个标识符就是公开的,即被包外的代码可见。

那么问题出现了,如果我想要访问这个alertCounter怎么办。我们在C#和java当中也遇到过,想要访问一个private的对象,我们当时使用的是 Get和Set方法,对对象进行取值和赋值。

func New(value int) alertCounter {
return alertCounter(value)
}

此时再通过main方法调用New方法,就可以得到一个alertCount的对象了

func main() {
// 虽然 main.alertCounter 是一个未导出的标识符
// 但是可以用短变量声明操作符捕获未导出类型的变量
counter := counters.New()
fmt.Printf("Counter: %d\n", counter)
}

运行结果如下:

Counter: 

将工厂函数命名为New 是Go 语言的一个习惯。这个New 函数做了些有意思的事情:它创建了一个未公开的类型的值,并将这个值返回给调用者。

为什么这个New能够执行?

要让这个行为可行,需要两个理由。

第一,公开或者未公开的标识符,不是一个值。

第二,短变量声明操作符,有能力捕获引用的类型,并创建一个未公开的类型的变量。(这句话就是上面 counter := counters.New(10) counter就是那个未公开类型的变量)永远不能显式创建一个未公开的类型的变量,不过短变量声明操作符可以这么做。看下面的例子。

// --- package a ---
type stu struct {
name string
age int
}
func NewStu() stu {
return stu{name: "a", age: }
}
// --- package main ---
func main() {
v := a.NewStu() // OK,v 的类型是 stu,虽然 stu 对包外不可见
fmt.Println(v)
}

我们打印一下,上面的短变量声明后的counter的类型

func main() {
// 虽然invisible.count是一个未导出的标识符
// 但是可以用短变量声明操作符捕获未导出类型的变量
counter := counters.New()
fmt.Println("v1 type:", reflect.TypeOf(counter))
fmt.Printf("Counter: %d\n", counter)
}

结果正如我们所想:记住alertCounter是不能进行实例化的哦。

v1 type: counters.alertCounter

补充一:上面的第二点其实是短变量声明的一个有趣的地方,什么是短变量声明

https://blog.csdn.net/wo198711203217/article/details/60574503

http://wenchao.wang/2017/10/23/Go%20%E8%AF%AD%E8%A8%80%E5%AD%A6%E4%B9%A0%E6%B1%87%E6%80%BB/

A short variable declaration uses the syntax:

IdentifierList := ExpressionList

补充二:Golang - var 和 := 的使用

https://studygolang.com/articles/5294

Go语言中公开和未公开标识符对类型提升的影响

例子1

package entities

// User defines a user in the program.
type User struct {
Name string
email string
}

User是entities包中公开的类型,Name是公开的成员、email是未公开的成员

在main包调用一下

func main() {
// Create a value of type User from the entities package.
u := entities.User{
Name: "Bill",
email: "bill@email.com",
} fmt.Printf("User: %v\n", u)
}

提示了一个错误:unknown field 'email' in struct literal of type entities.User (but does have entities.email) ,这说明啊,即使User是公开的,它里面的成员如果是隐藏的,对于外面也是非公开的不能被访问

例子2

增加一个Admin公开 user变为非公开 Admin里面使用user作为嵌入,其他成员都是公开的

// Package entities contains support for types of
// people in the system.
package entities // user defines a user in the program.
type user struct {
Name string
Email string
} // Admin defines an admin in the program.
type Admin struct {
user // The embedded type is unexported.
Rights int
}

main

func main() {
a := entities.Admin{
Rights: ,
}
a.Name = "Bill"
a.Email = "bill@email.com" fmt.Printf("User: %v\n", a)
}

可以看到在创建a对象的时候,user是不可见的,但是a却能访问Name和Email两个user内的成员

换句话说,内部类型的公开类型对于外部类型也是公开的。

Go语言公开或未公开的标识符的更多相关文章

  1. 微软未公开的 SP

    一些用在SQL 2000的企业管理GUI中,并且不打算用于其他的流程.微软已预计将其中的一些存储过程从未来的SQL Server版本中删除(或已经删除了).虽然这些存储过程可能很有用并为你节省了很多时 ...

  2. 可怕!CPU暗藏了这些未公开的指令!

    大家好,我是轩辕. 我们知道,我们平时编程写的高级语言,是经过编译器编译以后,变成了CPU可以执行的机器指令: 而CPU能支持的指令,都在它的指令集里面了. 很久以来,我都在思考一个问题: CPU有没 ...

  3. (转载)MS SQL Server 未公开的加密函数有哪些?

    MS SQL Server 未公开的加密函数有哪些? 以下的文章是对MS SQL Server 未公开的加密函数的具体操作,如果你对其相关的实际操作有兴趣的话,你就可以点击了. MS SQL Serv ...

  4. SQL Server里一些未公开的扩展存储过程

    SQL Server里一些未公开的扩展存储过程 [转帖] 博客天地 www.inbaidu.com SQL Server里一些未公开的扩展存储过程 扩展存储过程(xp)是直接运行在SQL Server ...

  5. 利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)

    利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)作者:Tuuzed(土仔)   发表于:2008年3月3日23:12:38 版权声明:可以任意转载,转载时请 ...

  6. CListCtrlEx:一个支持文件拖放和实时监视的列表控件——用未公开API函数实现Shell实时监视

    一.需求无论何时,当你在Explorer窗口中创建.删除或重命名一个文件夹/文件,或者插入拔除移动存储器时,Windows总是能非常快速地更新它所有的视图.有时候我们的程序中也需要这样的功能,以便当用 ...

  7. blktrace未公开选项网络保存截取数据

    本文链接地址: blktrace未公开选项网络保存截取数据 我们透过blktrace来观察io行为的时候,第一件事情需要选择目标设备,以便分析该设备的io行为.具体使用可以参考我之前写的几篇:这里 这 ...

  8. 关于 Android 中未公开的类(用@hide隐藏的类)

    关于 Android 中未公开的类(用@hide隐藏的类) 摘自:http://wangsheng2008love.blog.163.com/blog/static/78201689201142643 ...

  9. PB Event ID 含义 内容浅析2 未公开的数据窗口事件

    原网址:https://www.cnblogs.com/lenya/archive/2010/11/12/3706971.html  (作者:Mark   Brown)         到目前为止,P ...

随机推荐

  1. java基础知识总结一:

      四种内部类 直接抛出异常 单例模式: 懒汉式单例.饿汉式单例.登记式单例     []关于内部类:  []关于异常: 直接捕捉并抛出异常:不需要给异常添加名字: if(i>10)throw ...

  2. 如何为 .NET Core CLI 启用 TAB 自动补全功能

    如何为 .NET Core CLI 启用 TAB 自动补全功能 Intro 在 Linux 下经常可以发现有些目录/文件名,以及有些工具可以命令输入几个字母之后按 TAB 自动补全,最近发现其实 do ...

  3. SQL Sever AlwaysOn的数据同步原理

    1. SQL Server AlwaysOn数据同步基本工作 AlwaysOn 副本同步需要完成三件事: 1.把主副本上发生的数据变化记录下来. 2.把这些记录传输到各个辅助副本. 3.把数据变化在辅 ...

  4. mssql sqlserver text数据类型专题说明

    摘要: 下文分享text数据类型的简介及处理text数据类型所涉及的函数,如下所示: text 数据类型简介: mssql sqlserver 常用数据类型简介 mssql sqlserver tex ...

  5. 使用C++对物理网卡/虚拟网卡进行识别(包含内外网筛选)

    简介 在Socket编程的时候,我们需要实时获取我们所需要的IP地址.例如在编写后门的时候,我们可能需要获得有效的外网IP或内网IP:有时候我们可能需要判断我们获取的是否是虚拟机网卡,这时候就需要对每 ...

  6. LeetCode算法题-Relative Ranks(Java实现)

    这是悦乐书的第248次更新,第261篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第115题(顺位题号是506).根据N名运动员的得分,找到他们的相对等级和得分最高的三个 ...

  7. log4j控制指定包下的日志

    最近观察日志发现如下两个问题: 1.项目用的是springboot项目,整合了rabbitmq,项目启动后,会自动监控rabbitmq谅解是否正常,导致控制台一直输出监控日志,此时就想阻止该类日志输出 ...

  8. springboot操作mongodb

    springboot操作mongodb 采用MongoRepository操作mongodb springboot版本2.1.2.RELEASE 注意的是:在运行应用程序时,会报错OSS Algori ...

  9. springboot在eclipse中运行使用开发配置,打包后运行使用生产环境默认配置

    java命令运行springboot jar文件,指定配置文件可使用如下两个参数中其中一个 --spring.config.location=配置文件路径 -Dspring.profiles.acti ...

  10. nginx加密,访问接口认证

    使用htpasswd加密做接口认证 首先,安装htpasswd: yum install -y httpd-tools mkdir -p /usr/local/src/nginx/ 设置用户以及密码: ...