我正在使用Smalltalk在Transcript窗口中输入1-9乘法表。
这是我的代码:
1 to: 9 do: [:i|
1 to: i do: [:j|
Transcript show: j.
Transcript show: ' * '.
Transcript show: i.
Transcript show: ' = '.
Transcript show: j * i.
Transcript show: ' '.
].
Transcript show: ' '; cr.
].
可以看出,上面的代码尽管工作正常,但看起来并不美观简洁。
我曾希望写下这样的话:
Transcript show: j '*' i '=' j * i.
不幸的是,他们错了。我记得C有一个非常好的方法来处理我的这个问题。
赞,printf("%d * %d = %d ", j, i, j * i);
在这种情况下,是否有更优雅的方法使Smalltalk代码更优雅?
彼得解决了这个问题。感谢。更多问题:
如何显示"逃脱角色"在Smalltalk。
我知道在C中,printf("%d * %d = %d\n", j, i, j * i);
似乎很好。
但是在Smalltalk中,Transcript show: ('{1} * {2} = {3}cr.' format: {i. j. i * j}).
不是好的。
我该如何解决?
答案 0 :(得分:3)
喜欢,printf("%d *%d =%d",j,i,j * i);
有一些格式化选项,但没有什么比得上printf(afaik)
'<1p> * <2p> = <3p>' expandMacrosWith: 2 with: 3 with: 2 * 3.
"same as the following:"
'<1p> * <2p> = <3p>' expandMacrosWithArguments: {2. 3. 2 * 3}.
'{1} * {2} = {3}' format: {2. 3. 2 * 3}.
因此您的代码可以重写为以下
1 to: 9 do: [ :i |
1 to: i do: [ :j |
Transcript
show: ('{1} * {2} = {3}' format: {j. i. j * i});
show: ' '
].
Transcript show: ' '; cr.
].
Strings中没有转义字符,唯一的例外是单引号(&#39;),你可以逃脱&#34;加倍('It''s doubled!'
)
要编写新行或制表符,您可以
将其输入字符串
a := 'two
lines'.
(请注意,StackOverflow用空格替换了标签:/)
加入字符串
b := 'two', String cr, String tab, 'lines'.
告诉写入流添加
c := String streamContents: [ :stream | stream << 'two'; cr; tab; << 'lines' ].
使用expandMacros
d := 'two<n><t>lines' expandMacros.
a = b = c = d
答案 1 :(得分:2)
我建议做两处修改:
让代码使用通用Stream
并将其与Transcript
dumpTableOn: aStream
<your code here>
然后评估
self dumpTableOn: Transcript
用两种方法拆分代码
dumpTableOn: aStream
1 to: 9 do: [:i |
1 to: i do: [:j |
self dump: i times: j on: aStream.
aStream space].
aStream cr]
dump: i times: j on: aStream
aStream
nextPutAll: j asString;
nextPutAll: ' * ';
nextPutAll: i asString;
nextPutAll: ' = ';
nextPutAll: (j * i) asString
以上是上述方法的详细版本
dump: i times: j on: aStream
aStream
print: j;
print: ' * ';
print: i;
print: ' = ';
print: j * i
请注意,#print:
不要求我们先将参数转换为String
。
另请注意,级联不会创建中间Strings
,而表达式
j asString, '*', i asString, '=', (j*i) asString
创建4个中间字符串(每个#,
一个)。没什么大不了的,除了我们不会充分利用Stream
协议,其唯一的目的是让客户免于连接它的需要。
答案 2 :(得分:1)
如果你更喜欢使用与printf
类似的东西,Squeak有expandMacrosWith:方法系列(浏览类String)。
你的例子可以写成:
1 to: 9 do: [:i|
1 to: i do: [:j|
Transcript show: ('<1p> * <2p> = <3p> ' expandMacrosWith: j with: i with: j*i)
].
Transcript show: ' '; cr.
].
expandMacros...
的接收者包含有角度的括号之间的占位符。我在Squeak中找不到相关文档,以下内容来自对Dolphin Smalltalk中等效实现的评论:
Expand the receiver with replacable arguments.
e.g.
'Hello <D><N><1P> <D>' expandMacrosWithArguments: #('World' 1).
'Hello <2?Good:Bad> <1S>' expandMacrosWithArguments: #('World' false)
<nD> expands the nth parameter using it's #displayString
<nP> expands the nth parameter using it's #printString
<nS> expands the nth parameter treating it as a <String>
<N> expands as a newline combination
<T> expands as a TAB
<n?xxxx:yyyy> if the nth parameter is true expands to 'xxxx' else 'expands to yyyy'