[英]Can I extend built-in String class with my methods
我发现没有内置的trim (strip)
方法从内置String
类中的字符串中删除前导和尾随空格。 我想用我的功能扩展它。 可能吗? 在这里使用示例,我尝试了以下代码:
String extend [
trimleading: str [ |ch ret flag|
ret := str. "make a copy of sent string"
flag := true.
[flag] whileTrue: [ "while first char is space"
ch := ret first: 1. "again test first char"
ch = ' ' "check if space remaining"
ifTrue: [ ret := (ret copyFrom: 2 to: ret size)] "copy from 2nd char"
ifFalse: [flag := false]
].
^ret "return modified string"
]
trim: str [ |ret|
ret := str.
ret := (self trimleading: ret). "trim leading spaces"
ret := (self trimleading: (ret reverse)). "reverse string and repeat trim leading"
^(ret reverse) "return re-reversed string"
]
].
oristr := ' this is a test '
('>>',oristr,'<<') displayNl.
('>>',(oristr trim),'<<') displayNl.
上面的代码不起作用,并给出以下错误:
$ gst string_extend_trim.st
>> this is a test <<
Object: ' this is a test ' error: did not understand #trim
MessageNotUnderstood(Exception)>>signal (ExcHandling.st:254)
String(Object)>>doesNotUnderstand: #trim (SysExcept.st:1448)
UndefinedObject>>executeStatements (string_extend_trim.st:23)
问题在哪里以及如何纠正? 谢谢。
编辑:以下代码有效,但它不会更改原始字符串:
String extend [
trimleading [ |ch ret flag|
ret := self. "make a copy of sent string"
flag := true.
[flag] whileTrue: [ "while first char is space"
ch := ret first: 1. "again test first char"
ch = ' ' "check if space remaining"
ifTrue: [ ret := (ret copyFrom: 2 to: ret size)] "copy from 2nd char"
ifFalse: [flag := false]
].
^ret "return modified string"
]
trim [ |ret|
ret := self.
ret := (self trimleading). "trim leading spaces"
ret := ((ret reverse) trimleading ). "reverse string and repeat trim leading"
^(ret reverse) "return re-reverse string"
]
].
oristr := ' this is a test '
('>>',oristr,'<<') displayNl.
('>>',(oristr trim),'<<') displayNl.
('>>',oristr,'<<') displayNl.
oristr := (oristr trim).
('>>',oristr,'<<') displayNl.
oristr trim
如何改变oristr
? 我不想写oristr := oristr trim
。
你已经解决的第一个问题:最初你定义了一个方法trim:
有一个参数但是发送了trim
而没有参数。
第二个问题是修改String到位。 您可以使用self at: index put: aCharacter
更改chars self at: index put: aCharacter
以及其他一些复制和覆盖范围的方法,但是您将无法更改String的大小(长度)。 在我知道的Smalltalks中,对象在创建后不能改变它们的大小。 因此,我建议您坚持使用较少的字符trim
新字符串。
有一种方法可以在系统中的任何地方交换另一个对象。 它被称为become:
。 但我认为你不应该在这里使用它。 根据Smalltalk实现,您可能最终会产生不必要的副作用,例如替换方法中的String文字(因此下一个方法调用实际上将使用不同的修剪字符串代替文字运行)。
您的代码与您链接的示例之间的区别在于,在示例中,它们是扩展自定义类,但您正在扩展核心类。 不同之处在于您应该加载代码并运行它的方式。 您应该使用GNU-Smalltalk中的Packages来构建它。 @lurker有一个很好的答案如何在gst中使用扩展类,如果你喜欢它,请阅读并提供它,我不想在这里复制信息。
要使代码适应String extend
:
String extend [
trimleading: str [ |ch ret flag|
ret := str. "make a copy of sent string"
flag := true.
[flag] whileTrue: [ "while first char is space"
ch := ret first: 1. "again test first char"
ch = ' '
ifTrue: [ ret := (ret copyFrom: 2 to: ret size) ] "copy from 2nd char"
ifFalse: [flag := false ]
].
^ ret "value is modified string"
]
trim [ | ret |
ret := self trimleading: self. "trim leading spaces"
ret := self trimleading: (ret copy reverse). "reverse string and repeat trim leading"
^ (ret reverse) "return re-reverse string"
]
].
oristr := ' this is a test '.
('>>',oristr,'<<') displayNl.
('>>',(oristr trim),'<<') displayNl.
('>>',oristr,'<<') displayNl.
oristr := (oristr trim).
('>>',oristr,'<<') displayNl.
您正在将消息#trim
发送到origstr
变量,因此您必须定义不带任何参数。 但是,这不适用于#trimleading:
所以我已经把你以前的代码放在那里。
注意:您应该真正了解self
关键字及其功能并理解它 - 您使用不正确。 您指定ret := self
值但不使用它,只需用下一个分配覆盖它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.