编辑:我一直在这里投票 . 仅仅为了记录,我不再认为这很重要 . 自从我发布之后我就不需要了 .
我想在Scala中做以下...
def save(srcPath: String, destPath: String) {
if (!destPath.endsWith('/'))
destPath += '/'
// do something
}
...但我不能因为 destPath
是一个val . 有没有办法将 destPath
声明为var?
注意:有类似的问题,但在所有这些问题中OP只是想修改数组 .
请不要建议以下内容:
改变输入参数通常被认为是糟糕的风格,并且更难以推理代码 .
我认为它在命令式编程中是有效的(Scala允许两者,对吧?)并且添加像 tmpDestPath
这样的东西只会增加混乱 .
编辑:不要误解 . 我知道字符串不可变,我不想引用引用,因为我不想修改调用者的数据 . 我只想修改调用者给我的字符串的本地引用(例如orig'/') . 我想仅在当前方法的范围内修改该值 . 看,这在Java中是完全有效的:
void printPlusOne(int i) {
i++;
System.out.println("i is: " + i);
System.out.println("and now it's same: " + i);
}
我不必创建新变量,我不必计算i 1两次 .
7 回答
你不能 .
你必须声明一个额外的
var
(或使用更实用的风格:-)) .简单的例子:
JVM不允许指向对象的指针传递(这是你在C中执行此操作的方式),因此您无法完全按照自己的意愿执行操作 .
一种选择是返回新值:
另一个是创建一个包装器:
那些用户必须在途中使用 . (当然,他们会被诱惑到
save("/here",Mut("/there"))
,它会丢弃改动,但是传递引用函数参数总是如此 . )编辑:你提出的建议是非专业程序员之间最大的困惑之一 . 也就是说,当您修改函数的参数时,您是修改本地副本(按值传递)还是原始(按引用传递)?如果您甚至无法修改它,很明显您所做的任何事情都是本地副本 .
就这样做吧 .
值得对实际发生的事情缺乏困惑 .
也许您可以让类型系统为您完成工作,因此您甚至不必担心每次都添加斜杠:
现在您根本不需要任何代码来更改输入
String
:确实,在开始时有一些设置,但是对于2.10版本中的隐式类,这将会更少 - 并且它会消除方法中的所有混乱,这是您所担心的 .
字符串对象在Scala(和Java)中是不可变的 . 我能想到的替代方案是:
返回结果字符串作为返回值 .
使用不是不可变的StringBuffer或StringBuilder,而不是使用String参数 .
在第二种情况下,你会有类似的东西:
EDIT
如果我理解正确,您希望将参数用作局部变量 . 你不能,因为所有方法参数都是Scala中的val . 唯一要做的就是先将它复制到局部变量:
以下是一些建议:
1)稍微更新你的功能
2)在调用save之前创建一个实用程序函数
不,Scala不允许这样做 . 其他人已经描述了一些低级别的解决方法(都很好),但我会添加更高级别的解决方法 . 对于这种字符串规范化目的,我使用后缀,前缀,removeSuffix和removePrefix等方法保留了对scala.String的pimped扩展 . 后缀和前缀追加或前置一个字符串到另一个字符串,除非后缀或前缀已经存在 . removeSuffix和removePrefix做的很明显,从另一个字符串的末尾或开头删除一个字符串(如果它存在) . 你的用例将被写入
如果你做了大量的数据分析或文件操作,这些方法非常方便,你不会相信你没有它们 .
我知道这是一个老问题,但如果您只是想重用参数名称: