String 子字符串在 Swift 中如何工作

2024-01-03

我一直在使用 Swift 3 更新一些旧代码和答案,但是当我使用 Swift 字符串和子字符串索引时,事情变得令人困惑。

具体来说,我正在尝试以下操作:

let str = "Hello, playground"
let prefixRange = str.startIndex..<str.startIndex.advancedBy(5)
let prefix = str.substringWithRange(prefixRange)

第二行给了我以下错误

“String”类型的值没有成员“substringWithRange”

我看到String现在有以下方法:

str.substring(to: String.Index)
str.substring(from: String.Index)
str.substring(with: Range<String.Index>)

一开始这些真的让我很困惑,所以我开始尝试索引和范围 https://stackoverflow.com/questions/39676939/how-does-string-index-work-in-swift-3。这是子字符串的后续问答。我在下面添加一个答案来展示它们是如何使用的。


以下所有示例均使用

var str = "Hello, playground"

Swift 4

字符串在 Swift 4 中进行了相当大的修改。现在当你从字符串中获取一些子字符串时,你会得到一个Substring输入 back 而不是 aString。为什么是这样?字符串是 Swift 中的值类型。这意味着如果您使用一个字符串来创建一个新字符串,则必须将其复制过来。这有利于稳定性(没有人会在您不知情的情况下更改它),但对效率不利。

另一方面,子字符串是对其来源的原始字符串的引用。这是来自文档 https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html说明了这一点。

无需复制,因此使用效率更高。但是,想象一下您从一百万个字符的字符串中得到了十个字符的子字符串。因为子字符串引用字符串,所以只要子字符串存在,系统就必须保留整个字符串。因此,每当您完成对子字符串的操作时,请将其转换为字符串。

let myString = String(mySubstring)

这将仅复制子字符串,并且保存旧字符串的内存可以是回收的 https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html。子字符串(作为一种类型)的寿命是短暂的。

Swift 4 的另一个重大改进是字符串(再次)是集合。这意味着无论你能对 Collection 做什么,你都可以对 String 做(使用下标、迭代字符、过滤等)。

以下示例展示了如何在 Swift 中获取子字符串。

获取子串

您可以使用下标或许多其他方法(例如,prefix, suffix, split)。你还需要使用String.Index而不是一个Int不过,该范围的索引。 (看我的另一个答案 https://stackoverflow.com/a/39676940/3681880如果您需要帮助。)

字符串的开头

您可以使用下标(注意 Swift 4 的单边范围):

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str[..<index] // Hello

or prefix:

let index = str.index(str.startIndex, offsetBy: 5)
let mySubstring = str.prefix(upTo: index) // Hello

甚至更简单:

let mySubstring = str.prefix(5) // Hello

字符串结尾

使用下标:

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str[index...] // playground

or suffix:

let index = str.index(str.endIndex, offsetBy: -10)
let mySubstring = str.suffix(from: index) // playground

甚至更简单:

let mySubstring = str.suffix(10) // playground

请注意,当使用suffix(from: index)我必须使用从末尾倒数-10。仅仅使用时没有必要suffix(x),只需要最后一个x字符串的字符。

字符串中的范围

我们在这里再次简单地使用下标。

let start = str.index(str.startIndex, offsetBy: 7)
let end = str.index(str.endIndex, offsetBy: -6)
let range = start..<end

let mySubstring = str[range]  // play

转换Substring to String

不要忘记,当您准备好保存子字符串时,应该将其转换为String这样旧字符串的内存就可以被清理掉。

let myString = String(mySubstring)

使用Int索引扩展?

我很犹豫是否要使用Int阅读文章后基于索引扩展Swift 3 中的字符串 https://oleb.net/blog/2016/08/swift-3-strings/作者:Airspeed Velocity 和 Ole Begemann。虽然在 Swift 4 中,字符串是集合,但 Swift 团队故意不使用Int索引。它还是String.Index。这与 Swift 字符由不同数量的 Unicode 代码点组成有关。必须为每个字符串唯一计算实际索引。

不得不说,希望Swift团队能找到一种抽象的方法String.Index将来。但在那之前,我选择使用他们的 API。它帮助我记住字符串操作不仅仅是简单的Int索引查找。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

String 子字符串在 Swift 中如何工作 的相关文章

随机推荐

  • “索引、关注”或“关注”有什么区别?

    下面的列表有什么区别 首先 你可能知道元机器人 标签 元机器人标签是告诉蜘蛛或爬虫要抓取或索引哪个页面 关注手段 页面将被抓取 没有关注意味着 页面不会被抓取 指数均值 您的页面显示在搜索结果中 无索引意味着 您的页面未显示在
  • Rails 3 SQL 查询选择与连接

    我的选择功能和连接有问题 这是我当前的查询 search Building joins INNER JOIN floors ON floors building id buildings id INNER JOIN spaces ON sp
  • 是否支持内存映射文件作为 uwp 应用程序和 win32 进程之间的 ipc

    官方文档没有正确说明 uwp 是否支持通过内存映射文件的 ipc 我正在研究 uwp 应用程序及其桌面扩展之间的 ipc 场景 虽然我可以使用创建内存映射文件System IO MemoryMappedFiles从 uwp 应用程序code
  • 在打字稿中导出实用函数?

    我正在尝试这样做 伪代码 export const isDefined Function
  • Spring Security 3.1.3 @EnableWebSecurity

    我无法找到 Spring Security 3 1 3 中哪个包包含 EnableWebSecurity 我已经添加了 core config web 和 ldap 安全包 但注释仍然不可用 是否已被其他注释替换 我认为 Spring Se
  • 使用 Blazor 单击提交后清除输入字段

    我想知道是否有人知道如何在按下保存按钮 已提交 后清除所有输入字段 当我返回页面时 我的价值观仍然存在 这是我正在使用的代码 page testform inject BlazorApp6 Data Person person inject
  • 解组单个元素列表失败

    我正在运行一个示例 我再也找不到了 布莱斯 道恩斯博客 http blog bdoughan com在 Glassfish 3 上使用 EclipseLink 2 5 MOXy for JAXB 服务 XmlRootElement XmlA
  • 如何在xsd中引用属性

    我尝试定义一个可以在后续元素定义中引用的属性
  • Python Pika - 消费者进入线程

    我正在开发一个带有后台线程的Python应用程序 用于消费来自RabbitMQ队列的消息 主题场景 我在按钮的 on click 事件上启动线程 这是我的代码 请注意 self receive command def on click st
  • MVC3 中的 CSS 背景图像

    我正在尝试为我的 MVC3 应用程序创建样式表 我不知道如何格式化背景图像 url background image url Content images gradient tile page top png or background i
  • python 错误:“模块”对象没有属性“AF_UNIX”

    这是我的Python代码 if name main import socket sock socket socket socket AF UNIX socket SOCK STREAM sock connect 0 0 0 0 4000 i
  • 重写函数而不删除静态属性

    如果我有一个这样的函数 function a console log a 然后分配一个静态属性 如下所示 a static foo 但是假设我想用另一个函数覆盖该函数 如下所示 var old a a function console lo
  • Spring data mongodb,如何设置SSL?

    到目前为止 我还没有找到关于该主题的良好解释 文档 我在用
  • fwrite 是原子的吗?

    一个简单的问题 我需要在我的程序中添加一些日志记录 如果两个进程在同一文件上使用 fwrite 但不是同一文件描述符 则写入的日志消息将是原子的或混合的 有长度限制吗 是定义了 ANSI C 行为还是定义了实现 如果后者在 MacOSX L
  • 以编程方式添加 SwitchCompat 错误

    我正在尝试添加android support v7 widget SwitchCompat以编程方式 我收到此错误 java lang NullPointerException Attempt to invoke interface met
  • 检查用户输入是否在txt文件中,使用批处理

    我正在为局域网联网计算机批量制作聊天风格的系统 我想检查用户名是否被占用 如果不允许 我如何检查用户在这一行中输入的内容 set p name2 我已经在测试文件中尝试过这个 但无法让它工作 startup set fail set nam
  • findOne 可以工作,但不能获取全部/查找

    findOne 工作正常 db collection updates function err collection collection findOne author req user id function err doc 我正在尝试获
  • getaddrinfo,我没有得到任何 canonname

    我正在尝试读取有关特定主机的所有信息并打印出所有信息 我可以读取并打印出所有地址 但我没有读取任何 ai canonname 首先 我认为我的示例 www google com www irs gov 没有规范名称 但过了一会儿我发现我根本
  • 如何从控制器中包含的模块渲染js模板?

    我在控制器关注点中有一个操作 该操作包含在控制器中 此操作不会呈现在 respond to 块下指定的 js erb 文件 如何正确获取控制器关注点中的操作以成功呈现 js erb 文件 或任何视图 是我的路线有问题吗 模块操作的链接 li
  • String 子字符串在 Swift 中如何工作

    我一直在使用 Swift 3 更新一些旧代码和答案 但是当我使用 Swift 字符串和子字符串索引时 事情变得令人困惑 具体来说 我正在尝试以下操作 let str Hello playground let prefixRange str