第四天:PHP 开发者快速掌握 Go 函数
作为PHP开发者,你早已熟悉function定义函数、参数传值/传引用、return返回结果的逻辑。Go的函数体系更严谨、功能更丰富——支持多返回值、命名返回值、可变参数,且函数本身可作为参数/返回值(一等公民)。今天我们就以PHP函数为参照,快速掌握Go函数的核心语法和差异化特性。
一、Go函数基础(对标PHP函数声明)
Go函数通过func关键字声明,语法结构与PHP函数类似,但有“强类型约束”“无函数重载”等差异,先看核心对比:
1. 基本声明语法
| 特性 | Go函数 | PHP函数 |
|---|---|---|
| 声明关键字 | func | function |
| 参数格式 | 参数名+类型(如name string),类型后置 | 参数名(可选类型提示),类型前置(如string $name) |
| 返回值 | 支持单/多返回值,需声明类型 | 仅单返回值,无需声明类型 |
| 函数重载 | 不支持(同名函数报错) | 支持(通过参数个数/类型区分) |
基础示例:Go函数 vs PHP函数
// Go函数声明(计算两数之和)
func add(a int, b int) int {
return a + b
}
// 调用函数(需在main中执行,Go无全局执行)
func main() {
res := add(10, 20)
fmt.Println(res) // 输出30
}PHP对应写法:
// PHP函数声明
function add(int $a, int $b) {
return $a + $b;
}
// 全局调用
$res = add(10, 20);
echo $res; // 输出30⚠️ 关键差异:
1. Go函数的参数/返回值必须声明类型,PHP仅为“类型提示”(非强制);
2. Go函数必须在包内声明,且只有main包的main函数是入口,无法全局调用;PHP函数可全局声明/调用。
2. 简化参数声明(同类型参数)
Go支持多个同类型参数合并声明类型,简化代码,PHP无此语法:
// Go:a和b均为int类型,只需写一次int
func add(a, b int) int {
return a + b
}PHP需逐个声明类型(或不声明):
// PHP:需逐个写int(或省略)
function add(int $a, int $b) {
return $a + $b;
}二、Go函数参数(对标PHP参数传递)
Go的参数传递只有“值传递”(无PHP的“传引用”),但可通过指针实现类似效果;同时支持“可变参数”,对标PHP的...$args。
1. 普通参数(值传递)
Go默认按值传递参数(复制参数值),函数内修改不会影响外部变量,对标PHP的默认传值:
// Go值传递
func modifyNum(num int) {
num = 100 // 修改的是副本,外部变量不变
}
func main() {
n := 10
modifyNum(n)
fmt.Println(n) // 输出10(无变化)
}PHP对应写法:
// PHP默认值传递
function modifyNum($num) {
$num = 100;
}
$n = 10;
modifyNum($n);
echo $n; // 输出10(无变化)2. 指针参数(对标PHP传引用)
Go无&$num传引用语法,但可通过“指针”传递变量内存地址,实现修改外部变量的效果:
// Go指针参数(对标PHP传引用)
func modifyNum(num *int) {
*num = 100 // 解引用,修改原变量的值
}
func main() {
n := 10
modifyNum(&n) // 传递变量地址
fmt.Println(n) // 输出100(已修改)
}PHP传引用写法:
// PHP传引用
function modifyNum(&$num) {
$num = 100;
}
$n = 10;
modifyNum($n);
echo $n; // 输出100(已修改)3. 可变参数(对标PHP ...$args)
Go支持可变参数(需放在参数列表最后),用...类型声明,对标PHP的...$args:
// Go可变参数(计算多个数的和)
func sum(nums ...int) int {
total := 0
// 遍历可变参数(本质是切片)
for _, num := range nums {
total += num
}
return total
}
func main() {
res1 := sum(1, 2, 3) // 传多个参数
res2 := sum(10, 20, 30) // 传任意个数
fmt.Println(res1, res2) // 输出6 60
}PHP可变参数写法:
// PHP可变参数
function sum(...$nums) {
$total = 0;
foreach ($nums as $num) {
$total += $num;
}
return $total;
}
$res1 = sum(1, 2, 3);
$res2 = sum(10, 20, 30);
echo $res1 . ' ' . $res2; // 输出6 60三、Go函数返回值(PHP无的核心特性)
PHP函数仅支持单返回值(需返回多个值时要封装为数组/对象),而Go原生支持“多返回值”“命名返回值”,是核心优势之一。
1. 多返回值(对标PHP返回数组)
Go可声明多个返回值类型,函数内return多个值,对标PHP返回数组的场景:
// Go多返回值(获取用户信息:姓名+年龄)
func getUserInfo() (string, int) {
return "张三", 30 // 返回两个值:字符串+整型
}
func main() {
// 接收多个返回值
name, age := getUserInfo()
fmt.Printf("姓名:%s,年龄:%d\n", name, age)
// 忽略某个返回值(用_占位)
_, age2 := getUserInfo()
fmt.Println("年龄:", age2)
}PHP对应写法(返回数组):
// PHP返回数组模拟多返回值
function getUserInfo() {
return ["张三", 30];
}
// 接收返回值
list($name, $age) = getUserInfo();
echo "姓名:{$name},年龄:{$age}\n";
// 忽略某个值
[, $age2] = getUserInfo();
echo "年龄:{$age2}";
}2. 命名返回值(Go独有)
Go可给返回值命名,函数内无需显式return值(仅写return即可),简化代码:
// Go命名返回值
func calculate(a, b int) (sum int, sub int) {
sum = a + b // 直接赋值给命名返回值
sub = a - b // 直接赋值给命名返回值
return // 无需写return sum, sub
}
func main() {
s, sb := calculate(10, 5)
fmt.Println(s, sb) // 输出15 5
}💡 适用场景:返回值较多时,命名返回值可提升代码可读性(明确每个返回值的含义)。
四、Go特殊函数类型(对标PHP匿名函数/闭包)
Go的函数是“一等公民”(可作为参数、返回值、赋值给变量),支持匿名函数、闭包,对标PHP的匿名函数/闭包,但语法更简洁。
1. 匿名函数(对标PHP匿名函数)
Go匿名函数无需命名,可直接赋值给变量或立即执行,对标PHP的function() {}:
// Go匿名函数
func main() {
// 赋值给变量
sayHello := func(name string) {
fmt.Printf("你好,%s\n", name)
}
sayHello("PHP开发者") // 调用
// 立即执行匿名函数
func(num int) {
fmt.Println("立即执行:", num)
}(100)
}PHP对应写法:
// PHP匿名函数
// 赋值给变量
$sayHello = function($name) {
echo "你好,{$name}\n";
};
$sayHello("PHP开发者");
// 立即执行匿名函数
(function($num) {
echo "立即执行:{$num}\n";
})(100);2. 闭包(对标PHP闭包)
Go闭包可捕获外部变量,对标PHP的use关键字,且无需显式声明(直接使用外部变量):
// Go闭包(捕获外部变量count)
func main() {
count := 0
// 闭包函数,捕获外部变量count
increment := func() int {
count++
return count
}
fmt.Println(increment()) // 输出1
fmt.Println(increment()) // 输出2
fmt.Println(count) // 输出2(外部变量已修改)
}PHP对应写法(需用use):
// PHP闭包(需use捕获外部变量)
$count = 0;
$increment = function() use (&$count) { // 传引用才能修改外部变量
$count++;
return $count;
};
echo $increment() . "\n"; // 输出1
echo $increment() . "\n"; // 输出2
echo $count . "\n"; // 输出2五、实战案例:PHP vs Go 函数综合使用
需求:定义函数,接收一个整数切片/数组,返回“总和”和“平均值”
Go写法(多返回值+可变参数)
package main
import "fmt"
// 接收可变参数,返回总和+平均值
func calcTotalAndAvg(nums ...int) (total int, avg float64) {
total = 0
for _, num := range nums {
total += num
}
// 计算平均值(需类型转换)
avg = float64(total) / float64(len(nums))
return
}
func main() {
t, a := calcTotalAndAvg(80, 90, 75, 85)
fmt.Printf("总和:%d,平均值:%.2f\n", t, a) // 输出总和:330,平均值:82.50
}PHP写法(返回数组模拟多返回值)
// 接收可变参数,返回总和+平均值
function calcTotalAndAvg(...$nums) {
$total = 0;
foreach ($nums as $num) {
$total += $num;
}
$avg = $total / count($nums);
return [$total, $avg];
}
list($t, $a) = calcTotalAndAvg(80, 90, 75, 85);
echo "总和:{$t},平均值:".number_format($a, 2)."\n"; // 输出总和:330,平均值:82.50五、今日小结
今天我们以PHP函数为参照,掌握了Go函数的核心特性:
Go函数用
func声明,参数/返回值必须指定类型,无函数重载;Go参数传递只有值传递,可通过指针实现类似PHP传引用的效果;
Go原生支持多返回值、命名返回值,无需像PHP那样封装数组;
Go函数是一等公民,匿名函数/闭包语法简洁,捕获外部变量无需显式声明。
明天我们将学习Go的数组、切片与Map(对标PHP的索引数组/关联数组),详解Go复合数据类型的使用场景和核心差异,继续用PHP思维快速上手。
