• Go 支持 OOP: 用 struct 代替 class


    其实go和php,java那些在对面向对象的处理很像,只不过go没有class类。

    Go 是面向对象吗?

    Go 中没有 Class 的概念,它其实不是一个纯粹的面向对象的编程语言。

    Go 有类型和方法,也支持面向对象的编程风格。但是没有类型层次的结构。Go 的接口是定义一组方法的集合的类型,这些接口使用简单且通用,它们也支持嵌入到其他类型中,方便提供与子类类似但不相同的东西。

    struct 代替 class

    Go 没有 class 但是有 struct ,可以给 struct 添加方法。还可以将数据和对数据的操作的方法进行绑定。这像是 Class。

    1. package modules
    2. type Users struct {
    3. Name string
    4. Age int
    5. Status bool
    6. }
    7. func (u Users) SetUserStatus(){
    8. u.Status = false;
    9. fmt.Printf("设置 %s 的状态为 %t \n ",u.Name,u.Status)
    10. }
    11. // main.go
    12. package main
    13. func main(){
    14. user := modules.Users{
    15. Name:"Tom",
    16. Age:12
    17. Status:false
    18. }
    19. user.SetUserStatus()
    20. }
    21. 复制代码

    以上代码定义了结构体 Users ,再绑定一个 setUserStatus 的方法,方法里就可以操作结构体的属性。在 mian 文件中我们就可以初始化一个 User 结构体的变量 user,然后操作该变量的方法。这和 Class 很相似。

    New() 函数代替构造函数

    在 C#、Java 中,创建一个类时都会自带一个不带参数的构造函数。那么在 Go 中可以使用 New() 方法发挥构造函数的作用。

    刚才在上面的 Demo 中我们定义并初始化了一个 Users 结构体的变量 user。当我们使用零值定义 Users 结构体时会怎么样?

    1. package main
    2. func main(){
    3. var u modules.Users
    4. u.setUserStatus()
    5. }
    6. // 执行 go run main.go 结果如下:
    7. 设置 的状态为 false
    8. 复制代码

    如你所见,使用零值创建的变量,没有有效的 name ,输出的结果中没有 name 值,只是一个空字符串。在 Java 语言中,我们经常会使用构造函数来解决这个问题,使用参数化的构造函数来创建有效的对象。比如 Java 程序中:

    1. // 在 java 语言中
    2. public class Users{
    3. public string Name
    4. Users(name){
    5. this.name = name;
    6. }
    7. }
    8. // 使用
    9. Users user = new User("Tom")
    10. 复制代码

    Go 不支持构造函数。为避免发生其他包访问类型为 Users 的结构体时定义零值的变量,产生无效的作用。通过提供一个名为 New 的函数,该函数用所需的值初始化类型 Users。

    在Go 中,将创建 T 类型值的函数命名为 NewT(params) 是一种约定。这将充当构造函数。当包里只有一种类型,则该约定就是将函数命名为 New(params), 而不是 NewT(params)。

    所以我们正确使用方式如下:

    1. package modules
    2. type users struct {
    3. name string
    4. age int
    5. status bool
    6. }
    7. func New(name string, age int, status bool) Users {
    8. user := users{name, age, status}
    9. return user
    10. }
    11. func (u Users) setUserStatus(){
    12. u.status = false;
    13. fmt.Printf("设置 %s 的状态为 %t \n ",u.name,u.status)
    14. }
    15. 复制代码

    从上面的代码上可以看到:

    • 我们将结构体 Users 改为私有的,它的字段也都设置为私有的,防止外部其他的包访问。因为我们不需要除了 modules 包外的其他地方访问 users 的字段,除非有其他特定场景需要。
    • 另外,增加了一个公有的 New 函数,该函数的参数就是 user 结构体的字段,并且返回一个新创建的 user 实例。

    使用只需调用 New 函数,这样就能防止创建不可用的 user struct 类型值。这也是创建 user 的唯一方法。

    1. // 使用
    2. package main
    3. func main(){
    4. user := modules.New("Jack", 30, true)
    5. user.setUserStatus()
    6. }
    7. 复制代码

    因此,Go 虽然不支持 class ,但我们可以有效的使用 struct 来代替 class ,并使用 New 函数来代替构造函数。这样就可以实现 OOP。


    作者:六号积极分子
    链接:https://juejin.cn/post/7120926520662556686
    来源:稀土掘金

  • 相关阅读:
    Netty进阶——粘包与半包(代码示例)
    写给Python社群的第8课:Python异常,你必须掌握的技术点
    Linux环境下的Java(JDBC)连接openGauss数据库实践
    53-54 - 被遗弃的多重继承
    双向链表的创建和遍历
    盘点 | 2022年上半年国内的电邮安全事件
    Java基础:常用类(四)
    【李宏毅机器学习】Domain Adaptation 域适应
    Python爬虫之Js逆向案例(9)-企ming科技之webpack
    苹果知名开发者怒“怼”:GitHub 不可信,俄罗斯开发者贡献的项目遭毁灭性打击
  • 原文地址:https://blog.csdn.net/dj1540225203/article/details/126055542