You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言如何实现接收任意切片并返回同类型切片的分页函数?

解决Go中具体类型切片无法传入[]interface{}参数的分页函数问题

问题原因

Go语言中,[]entity.Something 和 []interface{} 是完全不同的类型,无法直接转换。[]interface{} 本质是存储 interface{} 类型元素的切片,每个元素包含类型信息和值的指针;而具体类型切片(如[]entity.Something)是连续存储该类型实例的内存块,两者内存布局不同,因此直接传入会触发编译错误。

解决方案1:使用泛型(Go 1.18+ 推荐)

泛型是处理任意类型切片最简洁且类型安全的方式,无需后续类型断言:

// PaginateSlice 对任意类型切片执行分页操作,返回同类型切片
func PaginateSlice[T any](x []T, page, pageSize int) []T {
    maxSize := len(x)
    
    // 非法参数直接返回空切片
    if page < 1 || pageSize < 1 {
        return []T{}
    }

    start := (page - 1) * pageSize
    // 起始位置超出切片长度,返回空切片
    if start >= maxSize {
        return []T{}
    }

    end := start + pageSize
    // 结束位置超出切片长度,截断到末尾
    if end > maxSize {
        end = maxSize
    }

    return x[start:end]
}

调用示例:

var result []entity.Something
// 直接返回同类型切片,无需类型断言
result = utility.PaginateSlice(dataOfSomethingType, pagination.Page, pagination.PageSize)

解决方案2:使用反射(兼容Go 1.17及以下版本)

如果项目依赖低版本Go,可通过反射实现任意类型切片的分页:

import "reflect"

// PaginateSlice 通过反射实现任意类型切片的分页
func PaginateSlice(x interface{}, page, pageSize int) interface{} {
    v := reflect.ValueOf(x)
    // 校验输入是否为切片类型
    if v.Kind() != reflect.Slice {
        return nil
    }

    maxSize := v.Len()
    if page < 1 || pageSize < 1 {
        return reflect.MakeSlice(v.Type(), 0, 0).Interface()
    }

    start := (page - 1) * pageSize
    if start >= maxSize {
        return reflect.MakeSlice(v.Type(), 0, 0).Interface()
    }

    end := start + pageSize
    if end > maxSize {
        end = maxSize
    }

    return v.Slice(start, end).Interface()
}

调用示例:

var result []entity.Something
tmp := utility.PaginateSlice(dataOfSomethingType, pagination.Page, pagination.PageSize)
// 类型断言转换为目标切片类型
result, ok := tmp.([]entity.Something)
if !ok {
    // 处理类型转换失败的异常情况
}

内容的提问来源于stack exchange,提问作者Mateen Bagheri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 14:20:19