面向 PHP 开发人员的 Go 入门
最近,我开始为我的团队开发一个内部命令行应用程序。我的主要编程语言是 PHP,但我希望用一种可以在任何平台上运行且无需预先安装解释器的语言来创建这个程序。我还希望这个应用程序能够独立成一个二进制文件,以便于分发和安装。我下载了 Go 语言,惊喜地发现这门语言非常容易学习,而且我在短时间内就掌握了它,效率非常高。Go 的过程式编程模型与我的 PHP 思维非常契合,我很快就能快速启动并运行这个应用程序。不过,Go 与 PHP 有一些显著的区别,所以我想分享一下,以便将来其他想要学习 Go 的 PHP 开发人员参考。
安装
MacOS
我使用 Mac,因此我使用 Homebrew 安装了 Go:。brew install go
如果您的 Mac 上没有Homebrew,我强烈建议您使用它。
Windows 和 Linux
Go 网站提供适用于每个操作系统的下载,包括适用于 Windows 的引导安装程序,可简化安装。
入门
在 Go 中,每个 Go 项目的所有源代码都存储在名为 GOPATH 的目录下。默认情况下,GOPATH 设置为go
您的主文件夹,例如/Users/andrewdavis/go
。在 GOPATH 中,有一个bin
目录和一个src
目录。该bin
目录包含您作为依赖项下载的所有二进制文件。您需要将bin
文件夹添加到 PATH 环境变量中。您可以在终端的 .bashrc/.zshrc 文件中使用 执行此操作export PATH=$PATH:$(go env GOPATH)/bin
。要开始学习 Go,您可以通过在终端中运行以下命令下载 Tour of Go 程序go get golang.org/x/tour/gotour
。go get
使用提供的路径下载第三方依赖项的源代码和二进制文件。现在,您可以gotour
在终端中运行,它将启动一个 Web 服务器并将您的浏览器指向它。
要创建项目,请src
在 GOPATH 下创建一个目录:mkdir -p $GOPATH/src/helloworld
。打开该文件夹cd $GOPATH/src/helloworld
并创建一个名为 main 的文件touch main.go
。在该文件中,输入以下内容:
package main
import "fmt"
func main() {
fmt.Println("Hello world!")
}
所有 Go 程序的起点都是 main 包中的 main 函数。接下来,你可以运行go run main.go
该程序。你也可以运行go install
,程序将被编译并放入bin
目录中,以便你在终端中执行helloworld
并运行你的代码。
与 PHP 的主要区别
现在你已经搭建好了项目,可以开始探索 Go 的各种特性了。你首先会注意到的是,Go 中不再需要分号。语句的结尾是通过换行符来判断的。以下是一些我花了些时间才理解的差异:
变量
Go 是一种静态强类型语言,因此每个变量都会被赋予一个类型。函数中的变量使用:=
运算符赋值,该运算符会自动设置变量类型:name := "Andrew" // name is now a string
。要创建变量而不设置任何数据,或者在函数外部创建变量,则必须使用 var 关键字:var name string
。
If 语句
If 语句的工作方式与 PHP 中的相同,但是它们不需要在布尔值检查周围使用括号。这种差异一开始让我在阅读 Go 代码时感到困惑。不过,我认为它让代码更容易阅读一些。
package main
import "fmt"
func main() {
value := false
if value {
fmt.Println("Value is true")
} else {
fmt.Println("Value is false")
}
}
包与命名空间
Go 使用术语package
来命名其内容。如果您controllers
的 Go 代码中有一个名为 的文件夹,则该文件夹下的每个文件都以 开头package controllers
。要从另一个包导入控制器,您可以写import “helloworld/controllers”
。包中任何以大写字母开头的名称都可以在另一个包中使用。如果您func HelloWorld()
在 中有一个名为 的函数,controllers
则一旦导入,您就可以调用controllers.HelloWorld()
来运行该函数controllers
。任何不以大写字母开头的内容只能从同一个包中使用。不需要 private 或 public!
字符串
在 Go 中,所有字符串都必须用双引号括起来。Go 中的单引号值表示一个符文(一个 Unicode 码位)。我习惯用单引号输入字符串,因为这是 PHP 中的常见做法。适应始终使用双引号需要一些时间。
var name = "Andrew"
var copy = '©'
结构体与类
Go 没有class
像 PHP 那样的系统。相反,它使用结构体来建模自定义数据结构。你可以像这样编写一个结构体:
package main
type Cup struct {
name string
color string
volume int
}
您可以通过创建一个在函数名称前括号中引用结构的函数来向结构添加方法。
func (c Cup) nameAndColor() string {
return c.name + ": " + c.color
}
然后,您可以通过编写结构体名称并在花括号中传入其初始值来创建结构体实例。方法执行使用点符号。
func main() {
c := Cup{name: "Solo", color: "Red", volume: 12}
c.nameAndColor() // returns "Solo: Red"
}
要创建修改结构实例的方法,该方法必须引用指向该结构的指针:
func (c *Cup) crush() {
c.volume = 0
}
错误
在 Go 中,错误不像异常那样被处理。它没有抛出或捕获机制。相反,如果函数发生错误,错误就会从函数中返回。Go 支持从一个函数返回多个值。如果调用一个可能返回错误的函数,则必须检查错误是否为 nil 才能处理错误情况。
package main
import "fmt"
func GetName(name string) (string, error) {
if name == "Bob" {
return "", fmt.Errorf("Name cannot be Bob")
}
return name, nil
}
func main() {
name, err := GetName("Bob")
if err != nil {
fmt.Println("Uh-oh an error has occurred")
}
}
鳍
当然,关于 Go 还有很多东西需要学习,但希望本文能帮助你入门。有很多很棒的资源可以帮助你学习 Go。对我来说最有帮助的是Go 文档和Go By Example。如果你有任何想法或问题,请留言。感谢阅读!
PHP 徽标来自PHP 网站。Go gopher
图像来自@egonelbre。