迹忆客 专注技术分享

当前位置:主页 > 学无止境 > 编程语言 > Go >

Go 面向对象 - New() 函数 替代 构造函数

作者:迹忆客 最近更新:2023/01/08 浏览次数:

我们在 GO 面向对象 - Structs 替代 Classes 这篇文章中写的程序看起来不错,但其中有一个微妙的问题。 让我们看看当我们用零值定义 employee 结构体时会发生什么。 将 main.go 的内容替换为以下代码

main.go

package main

import "oop/employee"

func main() {  
    var e employee.Employee
    e.LeavesRemaining()
}

我们所做的唯一改变是在第6行创建一个零值的 employee。该程序将输出以下内容

has 0 leaves remaining

go oop运行结果

正如你所见,使用 Employee 的零值创建的变量不可用。它没有有效的 first name、last name,也没有有效的 leave 详情。

在java等其他OOP语言中,这个问题可以通过使用构造函数来解决。可以使用参数化构造函数创建有效对象。

Go 不支持构造函数。如果类型的零值不可用,则程序员的工作是取消导出该类型以防止其他包访问,并提供一个名为 NewT(parameters) 的函数,该函数使用所需的值初始化类型 T。将创建 T 类型值的函数命名为 NewT(parameters) 是 Go 中的约定。它将充当构造函数的角色。如果包只定义了一种类型,那么 Go 中的约定就是将此函数命名为 New(parameters) 而不是 **NewT(parameters)**。

让我们对我们编写的程序进行更改,以便每次创建 Employee 时都可以使用它。

第一步是取消导出 Employee 结构体并创建一个函数 New() 来创建一个新的 Employee。将employee.go中的代码替换为以下内容

employee.go

package employee

import (  
    "fmt"
)

type employee struct {  
    firstName   string
    lastName    string
    totalLeaves int
    leavesTaken int
}

func New(firstName string, lastName string, totalLeave int, leavesTaken int) employee {  
    e := employee {firstName, lastName, totalLeave, leavesTaken}
    return e
}

func (e employee) LeavesRemaining() {  
    fmt.Printf("%s %s has %d leaves remaining\n", e.firstName, e.lastName, (e.totalLeaves - e.leavesTaken))
}

我们在这里做了一些重要的更改。我们在第7行将 Employee struct 的起始字母 E 改为小写,即我们将 Employee struct 类型改为 employee struct 类型。通过这样的修改,我们成功地取消了 employee 结构体的导出并阻止了其他包的访问。将未导出结构体的所有字段也设为未导出是一种很好的做法,除非有特定需求需要你导出它们。由于我们不需要在employee 包之外的任何地方访问employee 结构体的字段,因此我们也取消了所有字段的导出。

我们在 LeavesRemaining() 方法中相应地更改了字段名称。

现在,由于 employee 未导出,因此无法从其他包创建 employee 类型的值。因此,我们提供了一个导出用的 New 函数。 它将所需的参数作为输入并返回一个新创建的 employee。

该程序仍需进行更改以使其正常工作,但让我们运行它以了解到目前为止所做更改的效果。如果运行此程序,它会失败并显示以下编译错误

# oop
./main.go:6:8: undefined: employee.Employee

这是因为我们在 employee 包中有一个未导出的员工,并且无法从主包中访问它。 因此编译器会抛出一个错误,表明该类型未在 main.go 中定义。 完美的。 正是我们想要的。 现在没有其他软件包能够创建零值 employee 。 我们已成功阻止创建不可用的 employee 结构体值。 现在创建员工的唯一方法是使用 New 函数。

将 main.go 的内容替换为以下内容

main.go

package main  

import "oop/employee"

func main() {  
    e := employee.New("Sam", "Adolf", 30, 20)
    e.LeavesRemaining()
}

对该文件的唯一更改是第6行。通过将所需参数传递给新 New 函数,我们创建了一个新 employee(员工)。

下面是进行必要更改后的两个文件的内容。

employee.go

package employee

import (  
    "fmt"
)

type employee struct {  
    firstName   string
    lastName    string
    totalLeaves int
    leavesTaken int
}

func New(firstName string, lastName string, totalLeave int, leavesTaken int) employee {  
    e := employee {firstName, lastName, totalLeave, leavesTaken}
    return e
}

func (e employee) LeavesRemaining() {  
    fmt.Printf("%s %s has %d leaves remaining\n", e.firstName, e.lastName, (e.totalLeaves - e.leavesTaken))
}

main.go

package main  

import "oop/employee"

func main() {  
    e := employee.New("Sam", "Adolf", 30, 20)
    e.LeavesRemaining()
}

执行以下命令

$ go install oop
$ oop
Sam Adolf has 10 leaves remaining

go oop New函数执行结果

因此你可以理解,虽然 Go 不支持类,但可以有效地使用结构体代替类,并且可以使用全局函数 New(parameters) 来代替构造函数。

GO 面向对象 - Structs 替代 Classes这篇文章一起,构成了 Go 中的类和构造函数。

转载请发邮件至 1244347461@qq.com 进行申请,经作者同意之后,转载请以链接形式注明出处

本文地址:

相关文章

使用 C 语言中的 goto 语句

发布时间:2023/05/07 浏览次数:79 分类:C语言

本文介绍了如何在 C 语言中使用 goto 语句。使用 goto 语句在 C 语言中实现循环 goto 关键字是 C 语言的一部分,它提供了一个做无条件跳转的结构。

Django 中的 Slug

发布时间:2023/05/04 浏览次数:173 分类:Python

本篇文章旨在定义一个 slug 以及我们如何使用 slug 字段在 Python 中使用 Django 获得独特的帖子。

Django ALLOWED_HOSTS 介绍

发布时间:2023/05/04 浏览次数:181 分类:Python

本文展示了如何创建您的 Django 网站,为公开发布做好准备,如何设置 ALLOWED_HOSTS 以及如何在使用 Django 进行 Web 部署期间修复预期的主要问题。

Django 中的 Select_related 方法

发布时间:2023/05/04 浏览次数:129 分类:Python

本文介绍了什么是查询集,如何处理这些查询以及我们如何利用 select_related() 方法来过滤 Django 中相关模型的查询。

在 Django 中上传媒体文件

发布时间:2023/05/04 浏览次数:198 分类:Python

在本文中,我们简要介绍了媒体文件以及如何在 Django 项目中操作媒体文件。

Django 返回 JSON

发布时间:2023/05/04 浏览次数:106 分类:Python

在与我们的讨论中,我们简要介绍了 JSON 格式,并讨论了如何借助 Django 中的 JsonResponse 类将数据返回为 JSON 格式。

在 Django 中创建对象

发布时间:2023/05/04 浏览次数:59 分类:Python

本文的目的是解释什么是模型以及如何使用 create() 方法创建对象,并了解如何在 Django 中使用 save() 方法。

扫一扫阅读全部技术教程

社交账号
  • https://www.github.com/onmpw
  • qq:1244347461

最新推荐

教程更新

热门标签

扫码一下
查看教程更方便