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。

我认为唯一能够获得优化且 DRYer 的代码的方法是使用宏,但我认为这并不一定会导致更简洁的代码。

鉴于 string.clj 中其他函数的现有设计风格,我认为最好的解决方案是通过重复以提高代码的优化。

7 答案

0

评论者:sztamas

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

0

评论者:sztamas

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

0

评论者:jafingerhut

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

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

如果在不测试任意Unicode代码点的条件下进行这些API的增强,我没有异议。在过去的建议中,类似的建议在Clojure的内置库中被拒绝,例如CLJ-945

0
_评论者:sztamas_

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

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

我认为这很好,此外,因为高/低代理和高保真字符是互斥的,您可以实际上使用相同的实现来删除不在BMP中的Unicode代码点。您只需说这个代码点的最高和最低代码单元都是“不想要的”。

示例
0

评论者:jafingerhut

同意,但可能最好不要在trimr实现中推荐移除此类内容的做法,因为如果它匹配集合中的一个成员,它也会移除两个高/低位代理中的唯一一个UTF-16 Java字符,即使另一个代理在与集合中的任何内容不匹配的情况下,这会导致留下一个不规则的UTF-16字符串。

再次强调,最好根本不在实现中包括这一功能,最多在文档中警告这一点,或者在实现中通过在循环中检查高低代理来处理这一点。

0

评论者:sztamas

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

我稍微倾向于让trim?接受字符并且仅用于移除BMP字符。这可能会在绝大多数用例中足够。
另一种解决方案可以用于所有用例,但这时trim?必须接受int、2个字符或一个字符串,因此trim?将不那么直观(尽管更接近现实世界:-)),编写这些trim?函数将不太友好。

话虽如此,如果它被要求,我很乐意将实现更改为此。

目前,我甚至不确定这个增强是否会被接受或拒绝,也不知道这个过程是什么。

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