2024 年 Clojure 状况调查!中分享您的想法。

欢迎!请参阅关于 页面以了解更多有关此功能的详细信息。

0
Clojure
建议将 trim 函数(trim、triml 和 trimr)添加第二个参数为一个函数 {{trim?}}


[trim? ^CharSequence s]


{{trim?}} 首先支持部分功能。

新的文档字符串将为


"从字符串两端删除字符。
 如果省略 trim?,则删除空白。如果提供,则接受
 一个字符并返回如果应删除该字符则返回 true。"


示例测试


(deftest t-trim
  (is (= "foo" (s/trim "  foo  \r\n")))
  (is (= "bar" (s/trim "\u2000bar\t \u2002")))

  ;; 其他测试
  (is (= "bar" (s/trim "$%#\u2000bar\t \u2002%$#"
                       #(or (Character/isWhitespace %) ((set "$#%") %))))))



类似于 Python 的 strip - https://docs.pythonlang.cn/2/library/stdtypes.html#str.strip

*方法:* 建议的解决方案并不十分遵循 DRY 原则,但它遵循文件顶部的设计指南,更准确地说是第 3 点

"3. 函数利用字符串实现细节来
   编写高性能的循环/递归循环,而不是使用高阶
   函数。(这在通用应用程序
   代码中不是习惯用法。)"

起初,我有一个解决方案,其中我将当前实现中的 Character/isWhitespace 替换成调用 pred。pred 默认为 is-whitespace? 函数。
当然,这段代码更好,甚至 trim-newline 也可以直接调用 trimr,从而消除大量重复,但它增加了总是调用函数的开销,而不是直接调用 Character/isWhitespace。

我唯一能看到优化并更符合 DRY 原则的方法是使用宏,但我认为这并不一定会导致更好的代码。

考虑到 string.clj 中其他函数的现有设计风格,我认为最好的解决方案就是简单地复制以优化代码。

7 个答案

0

评论人:sztamas

建议的解决方案。代码 + 测试。

0

评论人:sztamas

新增了将 pred 重命名为 trim 的补丁?

0

评论人:jafingerhut

请注意,Java 以及 Clojure/Java 都在内存中使用 UTF-16 编码表示字符串。因此,如果要从字符串的开始和/或结束处删除一系列 Unicode 代码点,trim? API 只接收单个 16 位 Java 字符将无法确定是否应该被删除。

如果要处理这种通用性,将需要更复杂的实现,该实现会检查第一个/最后一个字符是否是表示一个由 2 个 16 位 Java 字符编码的代码点的一半,然后传递一个 32 位整数给 trim?,或者类似的某种方式。

如果在不启用针对任意 Unicode 代码点测试的情况下对这些 API 进行改进,我没有任何反对意见。过去,类似建议在 Clojure 的内置库中已被拒绝,例如 CLJ-945

0
_评论人:sztamas_

是的,UTF-16 编码以及代表代码点或半代码点的 Character 有点乱,不是吗?

在 Java String 和 Character API 中,接受 char 的方法只处理基本多语言平面(BMP)中的字符。
trim? 接受一个字符,因此遵循相同的行为,它将仅用于删除基本多语言平面中的字符。

我认为即便是这样也将没问题,但此外,因为高/低代理和 BMP 字符是分开的,你可以实际使用相同的实现来删除不在 BMP 中的 Unicode 代码点。你只需说代码点的两个代码单元“不需要”。

例如:
0

评论人:jafingerhut

同意,但可能最好反对推荐trimr这样的实现来删除这类内容,因为它如果匹配到集合中的成员,将会删除2个UTF-16代理字符中的1个,即使另一个代理字符在集合中没有匹配项,这将会留下一个格式错误的UTF-16字符串。

再次强调,最好完全不在实现中包括这一点,最多在文档中进行警告,或者通过在循环中检查高/低代理字符来处理它。

0
通过

评论人:sztamas

是的,你说得对。这个解决方案在所有情况下都不会工作,所以不能推荐。

我有点倾向于让trim?接受字符,并且只用于移除BMP字符。这将被认为足以处理大多数用例。
另一种方法可以用于所有用例,但是trim?将必须接受整数、2个字符或一个字符串,这使得trim?不太直观(虽然更接近现实 :-)),编写这些trim?函数将不太友好。

话虽如此,如果需要,我很乐意更改实现以实现这一点。

目前,我甚至不确定这个增强是否会得到接受或拒绝,或者这个过程是什么。

0
通过
参考: https://clojure.atlassian.net/browse/CLJ-1889(由sztamas报告)
...