MST
星途 面试题库

面试题:Go语言中结构体实参与形参传递的优化

假设你有一个包含大量字段的结构体 `LargeStruct`,现在需要将其作为参数传递给一个函数。从性能角度考虑,应该如何选择传递方式(值传递还是指针传递)?说明两种传递方式在内存使用和数据修改方面的差异,并给出代码示例。
16.4万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试
  1. 传递方式选择
    • 从性能角度考虑,对于包含大量字段的 LargeStruct 结构体,应选择指针传递。因为值传递会复制整个结构体,当结构体很大时,复制操作会消耗大量时间和内存;而指针传递只传递一个指针(通常是4字节或8字节,取决于系统架构),效率更高。
  2. 内存使用差异
    • 值传递:在函数调用时,会在栈上为传入的结构体副本分配内存空间,其大小与 LargeStruct 结构体本身大小相同。这意味着如果 LargeStruct 结构体很大,会占用较多的栈空间。
    • 指针传递:在函数调用时,仅在栈上为指针分配内存空间,通常是4字节(32位系统)或8字节(64位系统),相比值传递,大大减少了栈上的内存开销。
  3. 数据修改差异
    • 值传递:函数操作的是结构体的副本,对副本的修改不会影响原结构体的数据。
    • 指针传递:函数通过指针直接操作原结构体的数据,对指针所指向的数据的修改会反映到原结构体上。
  4. 代码示例(以C语言为例)
#include <stdio.h>

// 定义LargeStruct结构体
typedef struct {
    int data[1000];// 假设包含大量数据
} LargeStruct;

// 值传递函数
void modifyByValue(LargeStruct s) {
    s.data[0] = 100;
}

// 指针传递函数
void modifyByPointer(LargeStruct *s) {
    s->data[0] = 200;
}

int main() {
    LargeStruct original;
    // 初始化数据
    for (int i = 0; i < 1000; i++) {
        original.data[i] = i;
    }

    LargeStruct copy = original;
    modifyByValue(copy);
    printf("After value - passing, original.data[0] = %d\n", original.data[0]);

    modifyByPointer(&original);
    printf("After pointer - passing, original.data[0] = %d\n", original.data[0]);

    return 0;
}

在上述代码中,modifyByValue 函数采用值传递,对副本的修改不会影响原结构体;modifyByPointer 函数采用指针传递,对指针所指向的数据的修改会影响原结构体。