Go作为粘合剂:与Python、C及其他语言的集成

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么Go不是孤岛,而是桥梁

\n\n

Go是一种出色的语言。它快速、可编译,并拥有优秀的标准库。但让我们坦诚地说:在现实世界中,我们很少只用一种语言从头编写所有内容。您可能有一个经过时间考验的旧版C库,舍不得重写。或者一个用于机器学习的优秀Python脚本。又或者您想在浏览器中直接运行Go逻辑。

\n

于是问题来了:如何将Go与其他语言集成?别担心,Go被特意设计成一个好“邻居”。在PythonLib的这篇文章中,我们将探讨让您的Go程序与外部代码协同工作的三种主要方法。您将了解cgo的工作原理、如何通过系统调用调用Python函数,甚至如何将Go编译为WebAssembly。

\n\n

通过cgo将Go与C集成:经典方法

\n\n

最直接、最强大的途径是cgo。这不是一个库,而是Go内置的机制,允许您的代码直接调用C函数。它是如何工作的?您只需导入"C",并在其前面加上包含C代码的注释。Go编译器会将一切拼接起来。

\n\n

编写第一个cgo程序

\n\n

让我们编写一个简单的示例:从C中调用标准的printf。创建一个main.go文件:

\n\n
package main\n\n/*\n#include <stdio.h>\n#include <stdlib.h>\n\nvoid hello_cgo(const char* name) {\n    printf("来自C的问候,%s!\\n", name);\n}\n*/\nimport "C"\nimport "unsafe"\n\nfunc main() {\n    name := C.CString("Gopher")\n    defer C.free(unsafe.Pointer(name))\n    C.hello_cgo(name)\n}\n
\n\n

运行:go run main.go。如果您已安装GCC(或在Windows上安装了MinGW),一切将编译成功。您将看到“来自C的问候,Gopher!”。太神奇了!

\n\n

重要提示:C.CString在C堆中分配内存,因此我们必须通过C.free释放它。否则会导致内存泄漏。Cgo要求您具备良好的纪律性。

\n\n

传递复杂类型:结构体

\n\n

通常我们需要处理字符串以外的类型,例如结构体。假设我们有一个用于矩阵运算的C库。我们想将Go结构体传递给它。具体操作如下:

\n\n
package main\n\n/*\ntypedef struct {\n    int x;\n    int y;\n    int result;\n} Point;\n\nPoint add_points(Point a, Point b) {\n    Point r;\n    r.x = a.x + b.x;\n    r.y = a.y + b.y;\n    r.result = r.x + r.y;\n    return r;\n}\n*/\nimport "C"\nimport "fmt"\n\ntype GoPoint struct {\n    X, Y, Result int\n}\n\nfunc main() {\n    a := C.Point{x: 10, y: 20}\n    b := C.Point{x: 30, y: 40}\n    r := C.add_points(a, b)\n\n    goPoint := GoPoint{\n        X:      int(r.x),\n        Y:      int(r.y),\n        Result: int(r.result),\n    }\n    fmt.Printf("Go收到:Point{X:%d, Y:%d, Result:%d}\\n", goPoint.X, goPoint.Y, goPoint.Result)\n}\n
\n\n

请注意:我们显式地将C类型转换为Go类型。Cgo无法自动映射结构体,因此您始终负责转换。这是Go与C语言集成的主要权衡之一。

\n\n

何时不需要cgo

\n

在以下情况下不要使用cgo:

\n
    \n
  • 您只需要在终端中调用命令——请使用os/exec。
  • \n
  • 您正在编写跨平台代码——cgo会使构建过程复杂化。
  • \n
  • 性能不是关键——cgo会增加上下文切换的开销。
  • \n
\n\n

将Go与Python集成:智能脚本化

\n\n

Python和Go是一对绝佳搭档。Go负责速度和并发,Python负责灵活性和生态系统(NumPy、TensorFlow)。如何让它们协同工作?我们有两种方法:“重量级”(通过cgo和Python C API)和“轻量级”(通过子进程)。

\n\n

方法1:通过os/exec调用Python(简单可靠)

\n\n

对于教育目的来说,最安全的方法是将Python脚本作为独立进程运行。

博客

书籍推荐