【问题标题】:How to construct a String instance from a sequence of integers?如何从整数序列构造 String 实例?
【发布时间】:2015-12-11 21:37:20
【问题描述】:

我想从 Unicode 代码点创建一个测试字符串

类似的东西

 65 asCharacter asString,
 66 asCharacter asString,
 67 asCharacter asString,
 65 asCharacter asString,
769 asCharacter asString

或者

String with: 65 asCharacter
       with: 66 asCharacter
       with: 67 asCharacter
       with: 65 asCharacter
       with: 769 asCharacter

这可行,但是

我正在寻找一种将整数值数组转换为 String 类实例的方法。

#(65 66 67 65 769)

有内置的方法吗? 我正在寻找像 What is the correct way to test Unicode support in a Smalltalk implementation? 这样的答案,但对于字符串。

【问题讨论】:

  • 我认为即使有一种标准的方法,编写一个循环生成字符串或 StringBuilder 允许您自定义最终字符串的格式也是如此简单,它可能是最好继续写你自己的。祝你好运。
  • Squeak/Pharo 中没有 StringBuilder。这正是我想要的。

标签: string unicode smalltalk pharo squeak


【解决方案1】:

多种方式

1. #streamContents:

如果您要进行更大的字符串连接/构建,请使用流,因为它更快。如果只是连接几个字符串,则使用更具可读性的内容。

String streamContents: [ :aStream |
    #(65 66 67 65 769) do: [ :each |
        aStream nextPut: each asCharacter
    ]
]

String streamContents: [ :aStream |
    aStream nextPutAll: (#(65 66 67 65 769) collect: #asCharacter)
]

2。 #withAll:

String withAll: (#(65 66 67 65 769) collect: #asCharacter)

3. #collect:as: 字符串

#(65 66 67 65 769) collect: #asCharacter as: String

4. #joinUsing:角色

(#(65 66 67 65 769) collect: #asCharacter) joinUsing: ''

注意:

至少在 Pharo 中,您可以使用 [ :each | each selector ],或者直接使用 #selector。我发现后者对于简单的事情更具可读性,但这可能是个人喜好。

【讨论】:

    【解决方案2】:

    用#withAll构造String实例:

    String withAll: 
       (#(65 66 67 65 769) collect: [:codepoint | codepoint asCharacter])
    

    【讨论】:

      【解决方案3】:

      这是一个“低级”变体:

      codepoints := #(65 66 67 65 769).
      
      string := WideString new: codepoints size.
      codepoints withIndexDo: [:cp :i | string wordAt: i put: cp].
      ^string
      

      【讨论】:

        【解决方案4】:

        请考虑以下是非常骇人听闻的、无证的、不受支持的,因此是绝对错误的做法!
        你会认为你不能轻易地混合字符和整数,你可以:

        '' asWideString copyReplaceFrom: 1 to: 0 with: (#(65 66 67 65 769) as: WordArray).
        

        确实,这是通过一个不会真正检查类的原语,而只是因为接收者和参数都是 VariableWord 类的事实......

        出于同样的原因(取决于 WriteStream 实现 - 假设是脆弱的),这可以工作:

        ^'' asWideString writeStream
            nextPutAll: (#(65 66 67 65 769) as: WordArray);
            contents
        

        同样适用于 ByteString 和 ByteArray。

        当然,同样,我们不要忘记最复杂的方法,BitBlt:

        ^((BitBlt toForm: (Form new hackBits: (WideString new: 5)))
            sourceForm: (Form new hackBits: (#(65 66 67 65 769) as: WordArray));
            combinationRule: Form over;
            copyBits;
            destForm) bits
        

        我们再次利用 WideString 的 WordArray 特性作为表单位(位图)的容器。

        希望这个答案不会得到太多选票,不值得!

        【讨论】:

        • 感谢您的回答。它为实现提供了很多见解。
        • 但至少它会很快:)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-27
        • 1970-01-01
        • 1970-01-01
        • 2017-11-06
        • 1970-01-01
        • 1970-01-01
        • 2018-07-08
        相关资源
        最近更新 更多