当前位置:首页 > 文章列表 > Golang > Go问答 > Go x/text/transform ErrShortDst 为什么不代表输入非法

Go x/text/transform ErrShortDst 为什么不代表输入非法

来源:17golang原创 2026-10-27 06:30:01 0浏览 收藏

ErrShortDst 表示本次目标切片的空间不足,不能用来判断输入非法。它属于输出容量信号。输入是否合法,要看具体变换器的错误约定及应用自己的校验规则。正确处理的关键是先接收已经产生的输出、推进输入位置,再继续同一个变换器。

官方文档:https://pkg.go.dev/golang.org/x/text/transform

区分容量信号和输入合法性

Transform 返回 nDst、nSrc 和 err。前两个字段分别表示写入目标的字节数和消耗源数据的字节数;即使 err 非空,它们也可能包含有效进度。忽略这些计数,可能丢掉结果或者重复提交已处理输入。

返回信号含义处理重点
ErrShortDst目标空间不足保留输出并提供空间
ErrShortSrc当前源数据不足结合分块和结束标志处理
其他错误由具体实现定义按实现文档处理

如果源数据和输出空间同时不足,接口允许返回其中任一短缓冲区错误。因此,ErrShortDst 也不能证明输入没有其他问题。它只表达当前调用的一项受限条件。

输入输出字段与短目标错误的静态关系
源切片、目标切片、返回计数与容量信号的对应关系,连线不表示执行顺序。

用普通输入说明短目标错误

使用只复制字节的 transform.Nop,把普通 ASCII 输入交给较小目标区,就足以说明容量不足与非法输入是两回事。下面片段放在已导入 transform 的函数中;它用于解释接口,没有附带实测输出。

// 输入有两个字节,而目标只开放一个字节。
src := []byte("AB")
dst := make([]byte, 1)
nDst, nSrc, err := transform.Nop.Transform(dst, src, true)
// 使用输出和消耗计数后再解释 err,不能只判断错误字符串。
_, _, _ = nDst, nSrc, err

Nop 不承担 UTF-8 合法性检查。换成其他字符变换器,也应查清其替换、拒绝和错误报告策略。输入字节数与输出字节数没有通用的一比一保证,按 len(src) 分配 dst 不一定足够。

保留返回进度并连续转换

下面完整函数处理已经读齐的一份数据。atEOF=true 表示没有后续源数据,不意味着所有输出必须一次放完。每次调用都先记录输出和消耗量,再处理返回错误。

package example

import (
    "fmt"
    "golang.org/x/text/transform"
)

// ConvertAll 转换一份完整输入,错误时同时返回已产生的部分结果。
func ConvertAll(t transform.Transformer, input []byte) ([]byte, error) {
    const maxChunk = 65536 // 应用选择的单次缓冲区上限,不是库限制。
    t.Reset() // 独立任务开始时重置,循环中保持同一状态。
    dst := make([]byte, 8)
    src := input
    var result []byte
    for {
        nDst, nSrc, err := t.Transform(dst, src, true)
        result = append(result, dst[:nDst]...) // 先保留输出,再判断错误。
        src = src[nSrc:] // 下次只提交尚未消耗的输入。
        switch err {
        case nil:
            return result, nil
        case transform.ErrShortDst:
            if nDst == 0 && nSrc == 0 {
                if len(dst) == maxChunk {
                    return result, fmt.Errorf("输出缓冲区达到上限且没有进展")
                }
                dst = make([]byte, len(dst)*2) // 零进展时扩大空间,避免空转。
            }
            // 有进展即可复用工作区;不 Reset,也不丢失内部待输出数据。
        default:
            return result, fmt.Errorf("已消耗 %d 字节: %w", len(input)-len(src), err)
        }
    }
}

当调用产生进展时,可以复用同一工作区接收下一段输出。若 nDst 和 nSrc 同时为零,只用相同缓冲区原样重试可能持续失败,因此示例增大工作区并设置上限。64 KiB 是示例应用策略,需按实际变换器调整;函数会把完整结果累积到内存,大数据场景还应设置总输出限制或采用流式写入。

不能仅凭 nSrc 等于当前输入长度结束任务:变换器可能还有内部待输出数据。源数据耗尽后仍可用空 src 继续承接输出,直到成功或得到其他应处理的错误。循环中 Reset 会清除状态,不能把它当作处理 ErrShortDst 的修复动作。遇到其他错误时,调用者应明确处理部分结果,不能将它默认为完整成功。

连续变换中的状态和进度对象
同一变换器持有内部状态,剩余输入和累计结果分别依据自己的计数管理。

检查切片长度和接口选择

Transform 可写范围由 len(dst) 决定。make([]byte, 0, 1024) 的容量虽然是 1024,长度仍为零,直接传入并没有开放这部分空间。使用非零长度缓冲区,或者在明确用途后重新切片,才能让本次调用写入。

如果只是转换一份完整数据,可以使用 transform.Bytes 减少手写循环;它仍返回结果、消耗计数和错误。该函数会 Reset 变换器,因而不能随意插入正在进行的手动连续调用中。读取型任务也可考虑 transform.NewReader。手写循环适合需要明确掌握输出分段、工作区大小和部分结果策略的场景。

常见疑问

把 atEOF 改成 false 能解决吗?不能。它表达是否还有源数据,不能代替容量管理。实际分块场景还需要保留未消耗输入,并在真正结束时正确设置标志。

每次都要扩大缓冲区吗?不必。有进展时先排空输出并复用即可;零进展时调整空间策略,同时限制资源增长。

err 为 nil 是否就代表字符合法?不保证。完成变换和满足业务输入规范是两个判断。比如复制操作成功本身没有提供 UTF-8 检查。

排查时一起记录 len(dst)、nDst、nSrc、atEOF 和具体错误,能够分辨容量、分块及具体实现的问题,避免只保留一句“输入非法”。

参考:Transformer 接口、Bytes 文档。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go x/text/unicode/norm NFKC 为什么会改变兼容字符外观Go x/text/unicode/norm NFKC 为什么会改变兼容字符外观
上一篇
Go x/text/unicode/norm NFKC 为什么会改变兼容字符外观
Go x/text/unicode/bidi 片段顺序为什么不能直接反转字节
下一篇
Go x/text/unicode/bidi 片段顺序为什么不能直接反转字节
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    724次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    733次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    808次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    769次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    609次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码