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

欢迎!请查看 关于 页面以获取更多有关如何使用本网站的信息。

0
Clojure
建议将 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 中其他函数 existing 的设计风格,我认为最好的解决方案是简单地复制,以优化代码。

7 个回答

0

评论者:sztamas

提出解决方案。代码 + 测试。

0

评论者:sztamas

添加了一个新的补丁,将 pred 重命名为 trim?

0

评论者:jafingerhut

请注意,Java(以及Clojure/Java)在内存中使用UTF-16编码字符串。因此,如果您要从字符串的开始和/或结束处删除一系列Unicode代码点,trim?接口只接受一个16位Java字符,这不足以确定是否应该删除。

如果您想要处理这类通用性,就需要更复杂的实现,该实现会检查首位/最后一位字符是否是编码为两个16位Java字符的代码点的一半,并将32位int传递给trim?或类似的方法。

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

0
_评论者:sztamas_

是的,UTF-16编码以及Character类表示代码点或半代码点确实有点麻烦,不是吗?

在Java String和Character API中,接受char参数的方法仅处理基本多语言平面(BMP)中的字符。
trim?接受一个字符,所以根据同样的行为,它只能用于删除基本多语言平面中的字符。

我认为这本身就是没什么问题的,另外,因为高/低代理和高平面字符是相互独立的,您实际上可以使用相同的实现来删除不在BMP中的Unicode代码点。您只需要说代码点的高代码单元和低代码单元都是“不想要的”。

示例
0

评论者:jafingerhut

同意,但可能最好反对推荐这种对trimr的实现,用于移除这类事物,因为它还会在匹配到集合中的成员时,只会移除2个高/低代理字符中的1个UTF-16 Java字符,即使另一个代理字符在集合中没有匹配,这将会留下一个不规则的UTF-16字符串。

再次强调,最好是根本不要在实现中包含这个,最多在文档中提醒一下,或者通过在循环中检查高/低代理字符来在实现中处理这种情况。

0
是由

评论者:sztamas

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

我稍微倾向于让trim?接受字符并且只移除BMP字符。这或许对大多数用例来说足够了。
其他的解决方案可以用在所有的情况中,但trim?将不得不接受int、2个字符或一个字符串,这样trim?将不再直观(虽然接近现实 :-)),而且编写这些trim?函数将不太友好。

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

目前,我甚至不确定这个增强功能会被接受、拒绝,或者这个过程是什么。

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