[英]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.