• 请不要在回答技术问题时复制粘贴 AI 生成的内容
xrr2016
V2EX  ›  程序员

既然字符串是一个 char 数组, 为什么语言还要定义 String 的方法,而不是是直接用 Array 的方法?

  •  
  •   xrr2016 ·
    xrr2016 · Jul 15, 2017 · 6080 views
    This topic created in 3397 days ago, the information mentioned may be changed or developed.

    如题, 定义 String 的方法是否多此一举,增加了程序员的负担。

    44 replies  •  2017-07-16 17:25:06 +08:00
    choury
    choury
    Jul 15, 2017 via Android
    1
    你说的是 C 语言?然后再定义一堆,strlen strste strcmp strcap 等等函数?
    aprikyblue
    aprikyblue
    Jul 15, 2017
    2
    可 C 语言就是拿 char[]做字符串,也没 String 啊……
    xrr2016
    xrr2016
    OP
    Jul 15, 2017
    3
    @choury 在 javascript 里面也是, 既然 Array 有了 slice, splice 等方法,String 还要弄 substr, substring, 让我使用的时候还要纠结一下。
    Trim21
    Trim21
    Jul 15, 2017
    4
    在一个 array 中寻找另一个 array....
    linpf
    linpf
    Jul 15, 2017
    5
    可以把 string 理解为 array 的派生。虽然是个 array,但他是一个特殊的 array,有字符串操作方面的特性以及限制。
    wwjvtwoex
    wwjvtwoex
    Jul 15, 2017
    6
    正则表达式
    geelaw
    geelaw
    Jul 15, 2017❤️4
    7
    因为并不是所有的 char[] 都是有效的 string。

    譬如有的语言 / API 不允许 embedded null character。

    再比如多个 char 可能表示的是一个字符( UTF16 的 surrogate pair、UTF8 的 continuation ),数组长度并不总是和字符串长度之间有简单的等式关系。
    mooncakejs
    mooncakejs
    Jul 15, 2017
    8
    @xrr2016 char array 没有编码
    Perry
    Perry
    Jul 15, 2017 via iPhone
    9
    你确定是增加了负担?你想要知道一个 string 的长度没有 strlen 还不是要写一个 for loop ?
    0asis
    0asis
    Jul 15, 2017 via iPhone
    10
    一言以蔽之,抽象。
    就好比栈和队列实质上都可以用顺序的 array 存储,为什么还要定义这两个数据结构
    xrr2016
    xrr2016
    OP
    Jul 15, 2017
    11
    @Perry 有 length 属性啊
    Perry
    Perry
    Jul 15, 2017 via iPhone
    12
    slice 的方法要是直接用在 String 只能得到一个 char[] 而不是 String
    firemiles
    firemiles
    Jul 15, 2017
    13
    确认楼主没写过多少代码
    xieranmaya
    xieranmaya
    Jul 15, 2017
    14
    为了抽象
    ETiV
    ETiV
    Jul 15, 2017 via iPhone
    15
    既然 123 都是一二三
    <del>为什么四不写作 亖</del>

    一百不写作“一百个横”
    changwei
    changwei
    Jul 15, 2017 via Android
    16
    因为要考虑到多字节字符的使用,所以做了一下抽象会更加方便。

    比如说汉语,日语,韩语等字符,在不同的编码规则(比如说 unicode )以及编码实现(比如说 utf-8 )下,这些字符串的一个字符其实底层是多个 char 组成的。楼主试试看 php 里面的 strlen 和 mb_strlen 的区别就知道了。php 也是 c 写的,也可以看看 php 里面相关的源码来理解。
    misaka19000
    misaka19000
    Jul 15, 2017 via Android
    17
    哈哈 程序员的负担可比程序的负担重要多了,机器性能那都不是事
    xrr2016
    xrr2016
    OP
    Jul 15, 2017
    18
    @changwei 所以主要是因为有多种编码规则, 那么要是以后编码规则只有 Unicode 了, 就可以去掉 String 了吧.
    changwei
    changwei
    Jul 15, 2017 via Android
    19
    @xrr2016 嗯嗯,你就把 string 当做语法糖就好了。
    shihira
    shihira
    Jul 15, 2017❤️4
    20
    在多数的解释型语言里,抽象的成本比较高。在 js 当中,Array 是动态类型的 Array,并没有什么 Array of Char,其中每个元素都可以有不同的类型,于是访问每一个元素,解释器底层都要对这个元素识别类型、拆箱,才能开始计算,计算量 /复杂度可谓翻了个倍。但是明确钦定是 String 的时候,数据在内存里就是连续的、裸的字符序列,直接可以开始计算了。

    所以,在动态类型语言或者多数的解释型语言里,该用 String 的时候不要用 Array,这很重要。
    changwei
    changwei
    Jul 15, 2017 via Android
    21
    @xrr2016 也不是,utf8 这种实现一般情况下是三个字节代表一个汉字,如果用 array,做 substring 还得各种数学上的 x3,+1,-1 的计算,还是麻烦。
    Finest
    Finest
    Jul 15, 2017
    22
    这个问题我联想到,既然有 byte 数组,为啥还要定义 int,long
    shihira
    shihira
    Jul 15, 2017❤️3
    23
    同样,多数动态语言中 string 表现为 immutable,而 array 表现为 mutable,也是这个原因。
    xrr2016
    xrr2016
    OP
    Jul 15, 2017
    24
    @shihira 嗯, 多谢解释
    beginor
    beginor
    Jul 15, 2017 via Android
    25
    突然想起一个段子,计算机最终执行的不都是 0 1 么, 为啥还要整各种开发语言?
    sagaxu
    sagaxu
    Jul 15, 2017
    26
    @xrr2016 string 有一些特有的算法,比如忽略大小写的匹配,array 如何做到?
    AckywOw
    AckywOw
    Jul 15, 2017
    27
    因为人懒
    nbndco
    nbndco
    Jul 15, 2017 via iPhone❤️1
    28
    String 当前的实现几乎都复杂到一定境界了……怎么可能只是几个字符串匹配函数的目的而已……
    gyorou
    gyorou
    Jul 15, 2017
    29
    一般来说,string 可以看成是以某种编码下的 code point 的容器。这个容器可以是 list 或者是 array。
    所以感觉上来说,string 的抽象层次更高。
    这种抽象,无论是用面向对象概念的类来实现,还是通过 protocol 统一接口来实现,
    必然会有一系列名称和操作类似的方法或者函数。
    wohenyingyu02
    wohenyingyu02
    Jul 15, 2017
    30
    为什么是负担?你不想用完全可以不用
    zhicheng
    zhicheng
    Jul 16, 2017
    31
    C 语言教材和 C 语言标准库最大的错误就是让人觉得 C 有 “字符串” 这个类型,无论 char * 还是 char [] 都不是字符串,它们只是 “字节数组” ,C 标准甚至都没有规定 char 是 signed 还是 unsigned。同时 C 语言也没有规定一个字节是多少 bit。C 语言诞生的时候字符串没有现在这么重要,所以只是简单的 “约定” 了一下用 '\0' 结尾的字节数组作为字符串,并实现了相关函数。现在应该尽量避免用 '\0' 结尾的字节数组来模拟字符串。
    secondwtq
    secondwtq
    Jul 16, 2017
    32
    Haskell 就是和 C 一样直接拿 [Char] 当 String,不过用起来比 C 的要舒服得多
    虽然貌似实际多数人都在用 text ...
    wwqgtxx
    wwqgtxx
    Jul 16, 2017 via iPhone
    33
    当你学 c++11 14 17 的时候也会觉得很多东西都已经存在了,为什么 stl 还要实现一遍,最后当你能熟练运用这些库的时候你就会明白他存在的意义了
    congeec
    congeec
    Jul 16, 2017
    34
    @wwqgtxx std::array 用起来炒鸡爽
    xupefei
    xupefei
    Jul 16, 2017
    35
    有些字符串并不是简单的数组,例如 Windows API 常用的 UNICODE_STRING 结构体。
    msg7086
    msg7086
    Jul 16, 2017
    36
    其实就是,既然代码都是指令,为啥还要定义各种高级语言而不直接使用机器指令呢。
    增加程序员的负担?你说反了吧。
    yulon
    yulon
    Jul 16, 2017
    37
    C++ 的 string 都被喷成啥样了,这还有开倒车的。。。
    gnaggnoyil
    gnaggnoyil
    Jul 16, 2017
    38
    LZ 根本的问题还是没有区分开字符串和字符存储区的概念.在这一点上 C 的简单粗暴的抽象方式难辞其咎.

    不过同样让 C 难辞其咎的还有,部分评论中的字符和编码字符的字节区分不开来的趋势……
    Quaintjade
    Quaintjade
    Jul 16, 2017 via Android
    39
    Javascript 的 char[]形式是从 ES5 才开始规范的,所以像 IE7 之类远古浏览器不支持。
    shuson
    shuson
    Jul 16, 2017
    40
    用 c++做解释

    String 里包装了一个 array,帮你做 malloc 和 free,用\0 管理长度,并提供一系列方便的方法。
    cwek
    cwek
    Jul 16, 2017
    41
    C 的话忘记加\0 就字符串未结束了
    封装就是减轻开发负担,让程序帮你管理部分数据,封装的话可以用 length 来记录字符串长度,不用你管理。
    holy_sin
    holy_sin
    Jul 16, 2017
    42
    为了好用吧,所有的对象都是 bit,为什么还要定义数据结构呢,是这个道理吧
    hyyou2010
    hyyou2010
    Jul 16, 2017
    43
    字符串是人类语言层面的一句话,但这句话在不同计算机不同语言编码下会存储为各种不同的二进制 char 数组。我们往往需要在人类语言层面做操作,所以需要字符串这个比较高的表现层。
    yidinghe
    yidinghe
    PRO
    Jul 16, 2017 via Android
    44
    封装起来好。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   3238 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 116ms · UTC 10:41 · PVG 18:41 · LAX 02:41 · JFK 05:41
    ♥ Do have faith in what you're doing.