字符串或整个字符串的前n个字符;没有SubscriptOutOfBounds

时间:2019-02-04 12:20:45

标签: smalltalk pharo

在Pharo 7中,我试图获取字符串的第一个字符,或者仅获取整个字符串(如果请求的字符数超出字符串的长度)。

但是,以下示例导致错误,而我只希望它返回整个字符串:

    'abcdef' copyFrom: 1 to: 30. "=> SubscriptOutOfBounds Error"
    'abcdef' first: 30. "=> SubscriptOutOfBounds Error"
    'abcdef' first: 3. "=> 'abc'; OK"

如果请求的长度超过字符串长度,是否有一种方法可以返回整个字符串?

作为一种解决方法,我执行以下操作,首先检查字符串的长度,如果长度超过最大长度,则仅发送first:,但这不是很优雅:

label := aTaskbarItemMorph label size < 30 ifTrue: [ aTaskbarItemMorph label ] ifFalse: [ aTaskbarItemMorph label first: 30 ].

4 个答案:

答案 0 :(得分:5)

救援方法

我们还应该牢记,对于这种情况,我们在Pharo中拥有MethodFinder。您可以通过评估示例来使用它。就我们而言

MethodFinder methodFor: #(('abcdef' 30) 'abcdef' ('abcdef' 3) 'abc')

会产生

"'(data1 contractTo: data2) (data1 truncateTo: data2) '"

,其中包含已经提到的#truncateTo:,并添加了#contractTo:。请注意,后者实现了其他类型的起酥油技术,即

'abcdef' contractTo: 6 "'a...f'"

可能不是您今天想要的东西,而是一条将来可能有用的信息。


语法

MethodFinder的语法要求长度为Array的{​​{1}},其中每个示例都由一对( input arguments result )。

有趣的是,Squeak花括号使提供动态创建的示例变得容易:

2 * #examples

还将找到input := 'abcdef'. n := 1. MethodFinder methodFor: { {input. input size + n}. input. {input. input size - n}. input allButLast }

答案 1 :(得分:4)

  

字符串>> truncateTo:

'abcdef' truncateTo: 30. "'abcdef'"
'abcdef' truncateTo: 3. "'abc'"

答案 2 :(得分:2)

默认情况下,我在String类或其超类中看不到任何这样的方法。您的解决方法是一个很好的解决方案。

或者,更短的解决方法是使用min:选择字符串的大小或有限数量的字符。例如:

string := '123456'.
label := string first: (string size min: 5).

另一种解决方案是将扩展方法添加到String类中,该方法可以执行您想要的操作。因此,该方法将被添加到String类中,但会放入您的包中。例如:

String>>atMost: numberOfElement
    ^ self size < numberOfElement 
        ifTrue: [ self ] 
        ifFalse: [ self first: numberOfElement ]

然后执行以下操作:

string := '123456'.
string atMost: 2.  "'12'"
string atMost: 10. "'123456'"

在添加扩展方法时,您可以在名称中添加前缀,以避免可能的冲突,例如,以后将在Pharo中添加方法atMost:或另一个软件包也将定义这种扩展方法。

答案 3 :(得分:2)

这是一个简单的表达式,它将带来您想要的东西:

aString readStream next: n