ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Sway 字符串(Strings)完整指南:双引号规则、UTF-8 编码与不可索引限制

Sway 字符串(Strings)完整指南:双引号规则、UTF-8 编码与不可索引限制 Sway 字符串Strings完整指南双引号规则、UTF-8 编码与不可索引限制【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway本篇技术指南聚焦 Sway 语言中字符串String这一内置类型的核心规则与已知使用限制包括必须使用双引号声明、字符串为 UTF-8 编码且不可按索引访问等关键约束。读者读完本文后将能够正确声明 Sway 字符串、规避常见编译错误并理解其背后的类型系统与标准库实现原理为编写智能合约中的字符串处理代码打下基础。概述Sway 字符串的两大核心约束Sway 是 Fuel 生态中用于编写智能合约的领域特定语言。在 Sway 中字符串是最常用的内置类型之一但它与许多主流语言如 Rust、Python中的字符串在使用习惯上存在明显差异。根据 Sway 官方参考文档 workarounds/strings.mdSway 字符串主要有两条必须牢记的规则字符串必须使用双引号声明单引号不能被使用。尝试用单引号定义字符串会直接导致编译错误。字符串采用 UTF-8 编码因此不能按索引下标访问。试图通过str[index]获取某个位置的字符同样会触发编译错误。这两条规则看似简单却深刻影响了智能合约中字符串的声明与操作方式。下文将逐一展开并结合仓库源码与标准库实现进行深入剖析。规则一字符串必须使用双引号声明在 Sway 中字符串字面量string literal只能使用双引号包裹。官方文档给出的规则为Sway strings are declared using double-quotes. Single quotescannot be used. Attempting to define a string with single-quotes will result in an error.官方参考文档通过{{#include}}机制引入了仓库中的实际示例代码 string_issue/src/lib.sw用于演示错误用法// Will error if uncommented // let fuel fuel;也就是说以下写法在 Sway 中是非法的// 错误单引号不能用于声明字符串 let fuel fuel;正确的声明方式必须使用双引号let fuel fuel;为什么单引号不可用从 Sway 的类型系统设计来看单引号在语言中另有用途——它用于标记泛型类型参数generic type parameters例如abi MyContractT, U中的T、U等占位符。为了避免语法歧义并保持语言内部一致性字符串字面量被明确限定为双引号形式。这一设计决策使得编译器在词法分析阶段就能快速、无歧义地识别字符串字面量与泛型标识符从而简化解析流程。官方为验证这一限制专门创建了一个名为string_issue的库项目见 string_issue/Forc.toml其entry指向lib.sw并依赖仓库中的sway-lib-std标准库。示例代码中错误写法均被注释保留读者可自行取消注释并通过forc build观察编译错误输出。规则二字符串为 UTF-8 编码且不可索引官方文档给出的第二条规则为Strings are UTF-8 encoded therefore they cannot be indexed.仓库中的演示代码同样以注释形式展示了错误用法let fuel fuel; // Will error if uncommented // let f fuel[0];也就是说试图通过下标访问字符串中的字符如fuel[0]会引发编译错误。不可索引的深层原因UTF-8 变长编码Sway 字符串默认采用UTF-8 编码这一点在参考文档 language/built-ins/string.md 中也有明确说明。UTF-8 是一种变长编码ASCII 字符占用 1 个字节而其他 Unicode 字符可能占用 2、3 甚至 4 个字节。因此字符串中的第n个字符并不一定对应内存中的第n个字节无法通过简单的固定步长索引来定位某个字符。如果允许str[index]这样的操作编译器无法在编译期确定该索引指向的是一个完整字符还是字符中间的某个字节也就无法保证返回值的正确性与安全性。因此 Sway 语言直接禁止了对字符串的索引操作从而在类型层面规避了这一类潜在的错误。从源码看 Sway 字符串的内存表示Sway 标准库 str.sw 的实现揭示了字符串在底层的表示方式。str在底层被表示为(raw_ptr, u64)的元组——即指向字符串起始位置的原始指针 字符串字节长度impl str { /// Return a raw_ptr to the beginning of the string slice. pub fn as_ptr(self) - raw_ptr { let (ptr, _) __transmute::str, (raw_ptr, u64)(self); ptr } /// Return the length of the string slice in bytes. pub fn len(self) - u64 { let (_, len) __transmute::str, (raw_ptr, u64)(self); len } }从这段源码可以推断str本身并不携带字符级的信息只有字节指针与字节长度。这也从实现层面印证了不可索引的必然性——既然底层只保存字节数据而没有字符边界信息按字符索引自然无从谈起。字符串的长度固定长度类型在深入了解 Sway 字符串之前还需要明确一个关键前提Sway 的str是固定长度类型。参考文档 language/built-ins/string.md 明确指出其含义字符串在运行期间不能被增长grow或缩小shrink字符串的内容必须满足其声明长度——要么由合法内容恰好占满整个长度要么通过填充padding补齐原因在于编译器必须知道类型的尺寸而长度本身就是类型的一部分。字符串通过双引号创建时其长度被永久固定即使将变量标记为可变mut也无法改变let fuel fuel; // str[4]长度为 4由于长度属于类型的一部分Sway 中存在str[N]这种带编译期长度的字符串数组类型string array。固定长度特性与不可索引规则共同构成了 Sway 字符串少即是多的设计哲学类型信息在编译期完全确定为智能合约的安全性与可验证性提供了保障。字符串数组str[N]与可变长度str的转换既然长度是类型的一部分Sway 提供了字符串数组str[N]与字符串切片str之间的转换能力。仓库示例 examples/converting_types/src/strings.sw 演示了完整的转换流程pub fn convert_str_to_str_array() { let fuel_str: str fuel; let fuel_str_array: str[4] fuel_str.try_as_str_array().unwrap(); } pub fn convert_str_array_to_str() { let fuel_str_array: str[4] __to_str_array(fuel); let fuel_str: str from_str_array(fuel_str_array); }转换时编译器要求str[N]的编译期长度N与实际字符串长度完全一致如str[4]对应fuel否则会在编译期报错这正是长度属于类型的直接体现。标准库 str.sw 中from_str_array的实现展示了转换底层机制pub fn from_str_arrayS(s: S) - str { __assert_is_str_array::S(); let str_size __size_of_str_array::S(); let src __addr_of(s); let ptr asm(size: __size_of::S(), dest, src: src) { aloc size; move dest hp; mcp dest src size; dest: raw_ptr }; __transmute::(raw_ptr, u64), str((ptr, str_size)) }从这段代码可以看出from_str_array通过编译器内建函数获取字符串数组的尺寸与地址在内联汇编中借助aloc分配堆内存、mcp复制字节内容最终以(raw_ptr, u64)的形式transmute为str。整个转换过程完全发生在编译期与运行时的边界上进一步印证了字符串的类型安全设计。实战在智能合约中正确使用字符串综合以上规则在实际编写 Sway 代码时应遵循以下最佳实践1. 始终使用双引号声明字符串contract; // 正确 let network fuel; // 错误单引号会导致编译错误 // let network fuel;2. 不要对字符串使用索引访问// 错误字符串不可索引 // let first network[0];如需处理字符串中的单个字符应通过标准库提供的转换手段将字符串转为字节数据如std::string::String、Bytes后再按字节处理。3. 利用固定长度特性进行编译期校验字符串数组str[N]的声明让编译器在编译期即可校验长度适合对固定格式数据如合约地址格式、固定长度的标识符进行强类型约束。4. 需要动态字符串时使用标准库String当智能合约确实需要可增长的字符串时可以使用标准库 string.sw 中定义的String类型。它是一个UTF-8 编码、可增长的字符串拥有自己的缓冲区并提供from_ascii_str、len、push相关能力、as_str、clear、capacity等 API。String底层基于Bytes实现并实现了AbiEncode/AbiDecode、Hash、PartialEq、Clone等 trait可直接用于跨合约调用与存储场景。常见编译错误速查以下表格总结了本文涉及的两种错误场景便于快速排查错误写法错误原因正确写法let fuel fuel;单引号不能声明字符串let fuel fuel;let f fuel[0];字符串为 UTF-8 编码不可索引通过标准库转换后按字节处理这两类错误在 string_issue/src/lib.sw 中均有注释演示读者可结合forc build亲自验证。小结Sway 字符串的核心规则可以浓缩为两点双引号声明、UTF-8 编码不可索引。前者源于语言语法设计单引号保留给泛型参数后者源于 UTF-8 变长编码与底层(raw_ptr, u64)的字节级表示。加上字符串固定长度、长度属于类型的特性Sway 在字符串处理上展现出强烈的编译期安全倾向。理解这些约束是写出正确、高效的 Sway 智能合约代码的必修课。【免费下载链接】sway Empowering everyone to build reliable and efficient smart contracts.项目地址: https://gitcode.com/GitHub_Trending/sw/sway创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表