string - 为什么这个块没有修剪字符串
问题描述
我正在尝试以下块从发送的字符串中修剪前导空格:
trimleading := [ :str|
ch := (str byteAt: 1). "get first character: ERROR HERE"
ret := str copyFrom: 1. "make a copy of sent string"
[ch = ' '] whileTrue: [ "while first char is space"
ret := (ret copyFrom: 2). "copy from 2nd char"
ch := ret byteAt: 1. "again test first char"
].
ret "value is modified string"
].
('>>',(trimleading value: ' this is a test '),'<<') displayNl.
它可以正常工作,但不会从发送的字符串中删除前导空格。返回值与发送的字符串相同。
显然,第一个字符ch
没有被选中。at:
也不能代替byteAt:
.
问题出在哪里,如何解决?谢谢。
解决方案
问题是您将第一个元素作为字节(不是字符而是数字)与具有一个空格字符的字符串进行比较。在 Smalltalk 整数中,字符和字符串是不同的,所以你应该与相应的类型进行比较。at:
在这种情况下,您可以使用而不是获取字符串的第一个字符byteAt:
,或者与空格的 ascii 值(即 32)进行比较,或者Character space asciiValue
或$ asciiValue
。这是一种可能的解决方案:
trimleading := [ :str |
ch := str at: 1.
ret := str copyFrom: 1 to: str size.
[ ch = Character space ]
whileTrue: [ ret := ret copyFrom: 2 to: ret size.
ch := ret at: 1 ].
ret ].
^ ('>>' , (trimleading value: ' this is a test ') , '<<')
displayNl
您可能已经注意到,我更改copyFrom:
为copyFrom:to:
. 这是因为,与人们想象的不同,copyFrom:
它不会从传递到字符串末尾的位置复制,而是尝试从另一个对象复制接收者(此行为继承自Object
)。
您的代码还有很多其他可能的改进和简化,我将其留给您作为练习。
推荐阅读
- mysql - Mysql查询以获取恰好在1天前创建的记录
- spring-boot - 如何设置一个 Spring Boot 验证器,它可以使用 2x 传递的项目,但要求是任一值之一?
- java - 在构造函数中使用“this”的 Java 双向对象引用
- r - 使用 NA 将数据聚合到变量中
- haskell - 为什么可以声明高阶函数而不指定它们需要输入?
- java - 如何为自定义 Toast 消息设置自定义持续时间?
- excel - 如果文件名包含特定字符串“-Open”,则从下载中删除所有文件
- logging - 如何解决 Log4j2 找不到日志记录实现错误
- cross-compiling - 交叉编译到 ARM 目标硬件:出现错误:aarch64-linux-gnu-g++:错误:无法识别的命令行选项“-msse4.2”
- xcode - 尝试为 Mac 编译开源程序,但无法让 Cocoa 文件请求器和菜单正常工作