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

欢迎!请查阅关于页面以了解更多有关此信息的工作方式。

0 投票
Clojure
建议将修剪函数(trim、triml和trimr)获得第二个arity,即函数{{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 位 int 传递到 trim? 或类似实现。

如果在不启用针对任意 Unicode 代码点的测试的情况下进行这些 API 增强没有异议。在过去,类似的建议在 Clojure 嵌入式库中已被拒绝,例如 CLJ-945。

0 投票
_评论者:sztamas_

是的,UTF-16 编码和Character表示代码点或半代码点确实有点混乱,不是吗?

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

我认为这将没问题,但是,由于高/低代理和对基本多语言平面的字符是互斥的,您实际上可以使用相同的实现来删除不在基本多语言平面中的 Unicode 代码点。您可以只需说代码点的最高和最低代码单元都是“不需要的”。

例子:
0 投票

评论者:jafingerhut

同意,但可能最好不建议使用trimr来删除这类东西的实现,因为它会在匹配集合中的一个成员时,只去除2个高/低代理中的一个UTF-16 Java字符,即使另一个代理在集合中没有任何匹配项,这会留下一个格式不正确的UTF-16字符串。

再次强调,最好根本不将其包含在实现中,或者在最多的情况下在文档中发出警告,或者在实现中通过检查循环(s)中的高/低代理来处理。

0 投票
by

评论者:sztamas

是的,你是对的。这个解决方案在所有情况下都不会工作,因此不可推荐。

我稍微倾向于让trim?接受字符,并且只为删除BMP字符工作。这在理论上应该足够处理大多数使用情况。
另一种解决方案可以用于所有使用情况,但trim?将不得不接受整数、2个字符或字符串,因此trim?将不那么直观(尽管更接近现实世界 :-)),编写这些trim?函数将不太友好。

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

目前,我甚至不确定这个增强功能会被接受、拒绝还是如何处理这个过程。

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