MST

星途 面试题库

面试题:Go函数签名设计之专家难度题

设计一个Go函数签名,实现一个类似管道(pipeline)的功能,这个函数可以接收多个具有相同输入和输出类型的函数,将这些函数依次调用,前一个函数的输出作为后一个函数的输入,并返回最终结果。请详细阐述设计思路以及如何处理可能出现的错误情况。
12.2万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 函数签名设计:定义一个接受可变参数的函数,参数类型为函数类型,这些函数具有相同的输入和输出类型。返回值为最终经过一系列函数处理后的结果。
  2. 依次调用处理:在函数内部,通过循环依次调用传入的函数,将前一个函数的输出作为下一个函数的输入。
  3. 错误处理:如果任何一个函数调用过程中返回错误,立即停止后续函数调用,并返回该错误。

代码示例

package main

import (
    "fmt"
)

// Pipeline 定义管道函数,接受多个相同输入输出类型的函数,并依次调用
func Pipeline[T any](funcs...func(T) (T, error)) func(T) (T, error) {
    return func(input T) (T, error) {
        result := input
        for _, f := range funcs {
            var err error
            result, err = f(result)
            if err != nil {
                return result, err
            }
        }
        return result, nil
    }
}

错误处理说明

  1. 函数返回错误:在每个被传入的函数内部,如果发生错误,应立即返回错误。例如:
func addOne(x int) (int, error) {
    if x < 0 {
        return 0, fmt.Errorf("input cannot be negative")
    }
    return x + 1, nil
}
  1. Pipeline 处理错误:在 Pipeline 函数内部,当某个函数调用返回错误时,Pipeline 函数会立即返回该错误,不再继续调用后续函数。例如:
func main() {
    func1 := func(x int) (int, error) { return x * 2, nil }
    func2 := addOne
    pipe := Pipeline(func1, func2)
    result, err := pipe(-1)
    if err != nil {
        fmt.Println("Error:", err)
    } else {
        fmt.Println("Result:", result)
    }
}

在上述 main 函数中,func2 对负数输入会返回错误,Pipeline 函数在调用 func2 时接收到错误,会立即停止并返回该错误,main 函数捕获并打印错误信息。