字符串类型不可变的非技术好处

2024-02-19

我想知道从程序员的角度来看,字符串类型不可变的好处。

技术优势(在编译器/语言方面)可以概括为,如果类型是不可变的,则更容易进行优化。读here https://stackoverflow.com/questions/2916358/immutable-strings-vs-stdstring相关问题。

此外,在可变字符串类型中,要么已经内置了线程安全性(话又说回来,优化更难做到),要么必须自己做。在任何情况下,您都可以选择使用具有内置线程安全性的可变字符串类型,因此这并不是不可变字符串类型的真正优势。 (同样,进行处理和优化以确保不可变类型的线程安全性会更容易,但这不是这里的重点。)

但是不可变字符串类型在使用上有什么好处呢?让某些类型不可变而另一些类型不可变有什么意义呢?这对我来说似乎非常不一致。

在 C++ 中,如果我想让某个字符串不可变,我会将其作为 const 引用传递给函数 (const std::string&)。如果我想要原始字符串的可更改副本,我将其传递为std::string。仅当我想让它可变时,我才会将其作为参考传递(std::string&)。所以我只能选择我想做的事情。我可以用所有可能的类型来做到这一点。

在 Python 或 Java 中,某些类型是不可变的(主要是所有原始类型和字符串),而其他类型则不是。

在像 Haskell 这样的纯函数式语言中,一切都是不可变的。

存在这种不一致是否有充分的理由?或者仅仅是出于技术较低级别的原因?


拥有一些有什么意义 类型是不可变的,而其他类型不是?

Without some可变类型,你必须全力以赴地采用纯函数式编程——这是一种与目前最流行的面向对象编程和过程式方法完全不同的范式,虽然非常强大,但显然对很多程序员来说非常具有挑战性(什么当你发生时do在一种没有任何东西可变的语言中需要副作用,在现实世界的编程中,当然你不可避免地会这样做,这是挑战的一部分——HaskellMonads http://en.wikipedia.org/wiki/Monad_(functional_programming)例如,这是一种非常优雅的方法,但是您知道有多少程序员完全且自信地理解它们并可以使用它们以及典型的 OOP 结构?-)。

如果您不理解拥有多种可用范式(既是 FP 又是and那些关键依赖于可变数据),我建议学习 Haridi 和 Van Roy 的杰作,计算机编程的概念、技术和模型 http://www.info.ucl.ac.be/~pvr/book.html -- "a SICP http://mitpress.mit.edu/sicp/面向 21 世纪”,正如我曾经描述的那样;-)。

大多数程序员,无论是否熟悉 Haridi 和 Van Roy,都会欣然承认至少有some可变数据类型对他们来说很重要。尽管我在上面引用了你的问题中的一句话,它采取了完全不同的观点,但我相信这也可能是你困惑的根源:not“为什么其中一些”,而是“为什么有些”不可变的根本”。

“完全可变”的方法曾经(偶然)在 Fortran 实现中获得。如果你有,说,

  SUBROUTINE ZAP(I)
  I = 0
  RETURN

然后是一个程序片段,例如,

  PRINT 23
  ZAP(23)
  PRINT 23

会打印 23,然后是 0——23号已发生变异,因此程序其余部分中对 23 的所有引用实际上都引用 0。从技术上讲,这不是编译器中的错误:Fortran 对于程序在传递常量和传递常量时允许做什么和不允许做什么有微妙的规则变量分配给其参数的过程,并且此代码片段违反了那些鲜为人知的、编译器不可强制执行的规则,因此它是程序中的“但”,而不是编译器中的。当然,在实践中,这种方式导致的错误数量高得令人无法接受,因此典型的编译器很快就会在这种情况下转向破坏性较小的行为(如果操作系统支持,则将常量放入只读段中以获得运行时错误;或者,传递新鲜的copy尽管有开销,但还是常数而不是常数本身;等等)即使从技术上来说它们是程序错误,允许编译器非常“正确”地显示未定义的行为;-)。

在其他一些语言中强制执行的替代方案是增加多种参数传递方式的复杂性——最明显的是在 C++ 中,通过值、通过引用、通过常量引用、通过指针、通过常量指针,...当然,你会看到程序员对诸如此类的声明感到困惑const foo* const bar(其中最右边的const基本上是无关的,如果bar是某个函数的参数...但至关重要的是,如果bar is a 局部变数...!-).

实际上 Algol-68 可能在这个方向上走得更远(如果你可以有一个值和一个引用,为什么不是引用到引用?或者引用到引用到引用?&c - Algol 68 对此没有任何限制,并且规则定义正在发生的事情可能是在“真正使用的”编程语言中发现的最微妙、最困难的组合)。早期的 C(只有按值和按显式指针——没有const,没有参考文献,没有复杂性)无疑部分是对它的反应,就像最初的 Pascal 一样。但const很快,并发症又开始增加。

Java 和 Python(以及其他语言)用强大的简单大刀穿过了这片丛林:所有参数传递,and所有赋值都是“通过对象引用”(从不引用变量或其他引用,从不语义上隐式复制,&c)。将(至少)数字定义为语义上不可变可以避免“哎呀”(例如上面的 Fortran 代码所展示的情况),从而保持程序员的理智(以及语言简单性的这一宝贵方面)。

像数字一样将字符串视为基元与语言预期的高语义级别非常一致,因为在现实生活中我们do需要像数字一样易于使用的字符串;诸如将字符串定义为字符列表(Haskell)或字符数组(C)之类的替代方案对编译器(在此类语义下保持高效性能)和程序员(有效地忽略这种任意结构以使字符串的使用变得简单)都提出了挑战原语,正如现实生活中的编程经常需要的那样)。

Python 更进一步,添加了一个简单的不可变容器(tuple)并捆绑hashing到“有效的不变性”(这避免了程序员的某些意外,例如在 Perl 中,其散列允许可变字符串作为键)——为什么不呢?一旦你有了不变性(一个宝贵的概念,它可以让程序员不必学习 N 种不同的赋值和参数传递语义,其中 N 会随着时间的推移而增加;-),你可能会从中获得全部收益;-) 。

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

字符串类型不可变的非技术好处 的相关文章

随机推荐

  • PostgreSQL 9.2:citext[] 上的 GIN 索引

    我需要加快这个查询的速度 SELECT FROM mytable WHERE value ANY citext array col LIMIT 1 where citext array col是一个 citext 数组 我尝试创建一个运算符
  • 为什么我的 Django 视图在每个页面视图中都会被点击两次?

    我似乎一辈子都找不到问题所在 非常简单 我有一个从数据库中提取的数据库对象 将其 视图 增加一 然后保存 我的视图显示增加的值 但随后我的日志显示该值再次增加 g Game objects filter slug slug distinct
  • 将dataUrl转换为blob并通过ajax提交

    我正在使用 imgly 图像裁剪器插件 针对我的应用程序稍作修改 它当前将图像转换为dataUrl并将图像输出为 base64 图像 我可以将其另存为 jpeg 我正在努力调整dataURItoBlob找到函数here https stac
  • 无法打开文档“Main.Storyboard”。无法识别的文件内容

    从 Xcode 7 更新到 Xcode 8 后 我无法打开 Storyboard 有人可以帮忙吗 里面没有显示任何错误 对于我来说 将故事板打开为 源代码 修复合并冲突 然后重新启动 Xcode 就完成了这项工作
  • 使用 PHP 将二进制数据插入 SQL Server

    我在 SQL Server 2005 数据库中有一个 varbinary MAX 字段 我试图弄清楚如何使用 PHP 将二进制数据 即图像 插入到该字段中 我使用 ODBC 连接 SQL Server 数据库 我已经看到许多示例解释了如何与
  • Qt平台插件问题Rstudio

    我正在尝试通过 RStudio 绘制 seaborn 热图 I usereticulateR 中的包 下面是我的代码 library reticulate use condaenv python36 conda auto required
  • 如何用CLOB调用REPLACE(不超过32K)

    Oracle 11g 确实提高了 CLOB 的可用性 重载了大多数字符串函数 因此它们现在可以与 CLOB 一起本地工作 然而 一位同事从他的代码中得到了这个错误 ORA 22828 input pattern or replacement
  • 如何对 django url 进行单元测试?

    除了我的应用程序之外 我的应用程序在所有地方都实现了 100 的测试覆盖率urls py 你对我如何写作有什么建议吗有意义的对我的 URL 进行单元测试 FWIW 这个问题是在我尝试测试驱动开发时出现的 并且希望在编写代码来修复它们之前失败
  • 如何通过已知路由器上的三角测量来确定我的位置?

    有没有可用的开源软件 基本上 我只想根据位置固定且已知的路由器的信号强度进行三角测量 我意识到可能存在干扰的情况 但我们还是坚持列出已知的源代码 谢谢 我不知道任何三边测量软件 有人应该编写一个开源库 看看三边测量 http en wiki
  • 错误 NETSDK1064:找不到软件包 DnsClient,1.2.0

    我有一个 Asp Net core docker 镜像 我上次尝试构建它是两个月前 现在 我在尝试构建它时遇到错误 有任何想法吗 是不是有什么东西破坏了 Microsoft docker 镜像 当尝试在 Elasticbeanstalk 实
  • Python“数组索引太多”

    我正在使用 pandas 读取 python 中的文件 然后将其保存在 numpy 数组中 该文件的尺寸为 11303402 行 x 10 列 我需要拆分数据以进行交叉验证 为此我将数据切片为 11303402 行 x 9 列的示例和 1
  • 在 Cython 类中,使用 __init__ 和 __cinit__ 有什么区别?

    代码块1使用 init cython 3 cdef class c cdef int a str s def init self self a 1 self s abc def get vals self return self a sel
  • 服务器使用 HTTP Keep-Alive 与客户端通信

    最近在一次采访中 我被问到如何处理在线聊天客户端应用程序 我经历了标准的 轮询 解决方案 但被打断了 因为面试官正在寻找 HTTP 1 1 keep alive 方法 使用 HTTP 相当长一段时间并记住重点是 无状态 这对我来说从来没有发
  • 无法对测试运行“xxxx 2011-10-20 13:00:00”进行排队。您没有执行该操作的适当权限

    我正在尝试在 C VS2010 中运行我的测试用例 但突然有一天 它开始向我展示无法对测试运行 xxxx 2011 10 20 13 00 00 进行排队 您没有执行该操作的适当权限 错误 虽然我通过我的测试进行了调试 但无法选择并运行它
  • 如果连接丢失,从 SQL Server 到 Oracle 服务器的 OpenQuery 将无限期挂起

    我有一个在 SQL Server 2005 数据库上运行的计划作业 它运行一个从视图导入数据的存储过程 该视图由一个OPENQUERY到链接的 Oracle 服务器 我无法控制 Oracle 服务器 它在地理上和虚拟上都与 Sql Serv
  • 如何重命名本地 Git 分支?

    如何重命名尚未推送到远程存储库的本地分支 Related 重命名本地和远程 Git 存储库的 master 分支 https stackoverflow com questions 1526794 rename master branch
  • 如何在 Swift 中为 iOS 制作垂直文本 UILabel 和 UITextView?

    如果您根据标题提出这个问题 但对蒙古语不感兴趣 您可能会寻找以下问答 Swift 如何旋转 UIButton 和 UILabel 的文本 https stackoverflow com questions 28717634 swift ho
  • JSoup.clean() 不保留相对 URL

    我努力了 Whitelist relaxed Whitelist relaxed preserveRelativeLinks true Whitelist relaxed addProtocols a href http https mai
  • jQuery 检测 cookie 已启用

    我有一个基于 jQuery 的网络应用程序 我的要求相当简单 我想使用 jQuery 来查明用户是否在其 Web 浏览器中启用或禁用了 cookie 我知道有一个可用的插件可用于创建 检索 删除 更新 cookie 但是 有没有办法 jQu
  • 字符串类型不可变的非技术好处

    我想知道从程序员的角度来看 字符串类型不可变的好处 技术优势 在编译器 语言方面 可以概括为 如果类型是不可变的 则更容易进行优化 读here https stackoverflow com questions 2916358 immuta