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

欢迎!请参考关于页面,了解更多关于此的工作原理。

0
Clojure
建议将截断函数(trim、triml 和 trimr)获得一个第二参数,该参数是一个函数 {{trim?}}


[trim? ^CharSequence s]


{{trim?}}首先出现以支持部分应用。

新文档字符串将是


"从字符串的两端删除字符。
 如果省略trim?,则删除空白字符。提供时,它接受
 一个字符并返回一个布尔值,表示该字符应该被删除。


示例测试


(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. 函数利用字符串实现细节来
   编写高效的循环/递归而不是使用高阶
   函数。(这在通用应用程序
   代码中并不常见。)"

最初我有一个解决方案,我用 pred 调用替换了 Character/isWhitespace 的当前实现。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字符作为参数,这不足以确定是否需要去除。

如果您想处理这种普遍性,就需要一个更复杂的实现,该实现检查第一个/最后一个字符是否是编码为两个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个高/低代理字符中的1个UTF-16 Java字符,即使另一个代理中的字符没有匹配到集合中的任何内容,这会导致留下格式不正确的UTF-16字符串。

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

0

评论人:sztamas

是的,您是对的。这个解决方案并不适用于所有情况,因此不建议使用。

我稍微倾向于让trim?接受字符并仅针对去除BMP字符进行操作。这可能会在大多数用例中足够使用。
另一种解决方案可以用于所有用例,但trim?将必须接受整数、2个字符或一个字符串,因此trim?将不太直观(尽管更接近现实:-)),编写这些trim?函数将不再是友好用户。

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

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

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