【问题标题】:Import side effects导入副作用
【发布时间】:2018-01-24 16:59:49
【问题描述】:

我是 Go 和函数范式的新手。在 golang 中处理数据库连接时,我必须 import mysql 驱动程序。我遇到了“_”,这是指变量和导入包的空白标识符,它们的副作用是唯一的。

搜索副作用发现了这个side effects in es6

我不明白的是函数的副作用取决于一个全局变量,它偏离了纯函数的引用透明度。但是一个包怎么会带来副作用呢? 是不是因为依赖包的副作用?

例如:

import _ "github.com/go-sql-driver/mysql"

db, err := sql.Open("mysql", "user:password@/dbname")

这里的导入有“_”,因为Open 语句依赖于驱动程序名称?

【问题讨论】:

  • 这与函数式程序员在谈论纯函数时所指的副作用无关。这里的副作用是执行了包的init函数,注册了驱动。

标签: go functional-programming


【解决方案1】:

_ 导入感兴趣的主要副作用是init 函数的执行。一个包可以包含一个init 函数,该函数将在程序启动时执行,在main 执行之前。对于 DB 驱动程序,这用于注册驱动程序,以便您可以将其与sql.Open 一起使用; expvarpprof 包都在它们的 init 函数中注册 HTTP 处理程序,并且同样经常与 _ 导入一起使用。

这在Go spec section on package initialization 中有记录。

【讨论】:

  • import 确实在全局变量声明上执行init 函数和其他函数执行,例如var x = F()
  • 是的,但是一个编写良好的包会将其初始化副作用限制为init 函数并坚持不会产生副作用的全局变量声明。但是,是的,从技术上讲,它会以这种方式产生副作用。
  • 是的,但是 go 没有提供处理多个 init 函数顺序的方法,所以有时为了让事情先发生,全局声明导致“副作用”是一种解决方法.我同意任何好的做法都应该避免这种情况。
  • 它没有提供比init执行更多的对全局变量执行顺序的控制;根据规范,inits 是“按照它们在源代码中出现的顺序”执行的,而“包级变量按声明顺序初始化,但在它们依赖的任何变量之后” - 大致等价,尽管全局变量是稍微复杂一点。
  • 我的意思是,全局变量总是在初始化执行之前,可以利用这一点。全局变量和init 顺序都很脆弱,但前者总是在后者之前。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-05
  • 2021-03-03
  • 1970-01-01
  • 2020-08-15
  • 1970-01-01
相关资源
最近更新 更多