使用已记录的命名和位置参数(或具有默认值的 args)的混合,如何在不指定任何命名参数的情况下调用方法?
我试图在不破坏其他人的代码的情况下扩展现有的共享方法,这种方法看起来很有希望,但下面的例子失败了:
?def test(Map args, some, thing='default value'){
"$some $thing";
}
//good - adding any named parameter works
//test('yet', 'another good', anything:'notneeded');
//but not specifying named parameter fails
test('this', 'fails');???????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????????
Run Code Online (Sandbox Code Playgroud)
我无法找到有关此行为的文档,而且看起来很奇怪。
我目前正在开发一个与Oracle数据库交谈的经典ASP项目.我正试图找到一种方法来安全地调用Oracle PL/SQL脚本并使用ADO传递参数.当前的解决方案使用嵌入式变量手动构建SQL脚本,如下所示:
strSQL = "SELECT field1, etc FROM my_table WHERE (field = '" & filter_value & "')"
Run Code Online (Sandbox Code Playgroud)
当然,这是丑陋和不安全的,并且容易被滥用.
到目前为止我所拥有的代码(来自各种非经典的基于asp的网站)看起来像这样:
dim strSQL, oConn, oCommand, oParam
set oConn = server.createobject("ADODB.Connection")
oConn.Open myConnString
strSQL = "SELECT field1, etc FROM my_table WHERE (field = :filter_field)"
dim oFilteredList
set oFilteredList = Server.CreateObject("ADODB.Command")
oFilteredList.ActiveConnection = oConn
oFilteredList.CommandText = strSQL
oFilteredList.CommandType = adCmdText
oFilteredList.NamedParameters = True
set oParam = oFilteredList.CreateParameter("filter_field", adVarChar, adParamInput, 10, filter_value)
oFilteredList.Parameters.Append oParam
set rsResults = oFilteredList.Execute
Run Code Online (Sandbox Code Playgroud)
这会导致错误"参数对象未正确定义.提供的信息不一致或不完整"
使用ADO中的命名参数调用Oracle/PL/SQL的正确方法是什么?我需要使用命名参数,因为实际的SQL代码有点复杂,并且在整个SQL命令中多次使用不同的参数.
假设您有一个带有以下签名的方法:
public void SomeMethod(bool foo = false, bool bar = true) { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
调用此方法时,有没有办法为bar和不指定值foo?它看起来像......
SomeMethod(_, false);
Run Code Online (Sandbox Code Playgroud)
......这会转化为......
SometMethod(false, false);
Run Code Online (Sandbox Code Playgroud)
......在编译时.这可能吗?
使用场景:
# case #1 - for classes
a = MyClass() # default logger is None
a = MyClass(logger="a") # set the default logger to be "a"
a.test(logger="b") # this means that logger will be "b" only inside this method
a.test(logger=None) # this means that logger will be None but only inside this method
a.test() # here logger should defaults to the value specified when object was initialized ("a")
Run Code Online (Sandbox Code Playgroud)
我如何实现MyClass以便能够如上所述使用它?
让我们假设我有几个方法MyClass可以接受logger命名参数,所以我希望一个解决方案不需要在每个test...()方法的开头添加大量重复代码.
我读到了关于sentinel的例子 …
class Algo {
def a( a : String = "Hola ", b : String = "adios" ) {
print( a )
print( b )
}
def a() {
print ("Uh?")
}
}
object Algo {
def main( args : Array[String] ) {
new Algo().a()
}
}
Run Code Online (Sandbox Code Playgroud)
版画 Uh?
如果a()未定义方法,则代码使用默认值打印"Hola adios".
因此,我从中推断出,如果确切的签名匹配,那就是优先的.
这个推理是否正确?
简短版本:参数后面的命名参数out给出了编译器错误,但我在语言规范中找不到对此行为的任何支持.
长版:
我正在使用Enum.TryParse<TEnum>三个参数重载,但我更喜欢命名ignoreCase参数以使我的代码更清晰,调用如下:
MyEnum res;
b = Enum.TryParse<MyEnum>(inputString, true, out res);
Run Code Online (Sandbox Code Playgroud)
留下布尔不清楚的含义(除非这个方法已知1).因此我想用:
b = Enum.TryParse<MyEnum>(inputString, out res, ignoreCase: true);
Run Code Online (Sandbox Code Playgroud)
但是,编译器将此报告为错误:
命名参数'ignoreCase'指定已为其指定了位置参数的参数
并且IDE突出显示该ignoreCase参数.针对.NET 4的VS2010以及针对4或4.5的VS11 Beta都会产生相同的结果.在所有情况下,命名out参数都会删除错误.
b = Enum.TryParse<MyEnum>(inputString, result: out res, ignoreCase: true);
Run Code Online (Sandbox Code Playgroud)
我已经在框架和我的程序集中尝试了许多不同的方法(包括避免泛型)2:总是相同的结果:out参数后跟命名参数会产生错误.
我看不出有什么理由错误,并且第7.5.1节参数列表中的C#语言规范:4.0版似乎并没有提供任何理由的out,然后命名参数应该给出一个错误.错误的文本似乎支持解释为一个错误:没有位置参数可能是一个有效的匹配ignoreCase.
我对规范的解读是错误的吗?或者这是编译器错误?
C#7.2更新
当使用C#7.2解除调用时,对所有命名参数的这种限制必须遵循位置参数.
请参阅https://docs.microsoft.com/en-gb/dotnet/csharp/whats-new/csharp-7-2#non-trailing-named-arguments.
1因此,框架设计指南中的建议更倾向于enum参数.
2例如:给定:
private static void TestMethod(int one, float two, out …Run Code Online (Sandbox Code Playgroud) 我们正在使用Spring MessageSource在我们的应用程序中生成错误消息。
我们这样填充错误消息
dobInvalid = The DOB supplied {0} is invalid
Run Code Online (Sandbox Code Playgroud)
我们想使用命名参数,所以我们可以
dobInvalid = The DOB supplied {dob} is invalid
Run Code Online (Sandbox Code Playgroud)
在Api文档中查找getMessage似乎建议您执行以下操作: http://static.springsource.org/spring/docs/1.2.x/api/org/springframework/context/MessageSource.html
args-将为消息中的参数填充的参数数组(参数在消息中看起来像“ {0}”,“ {1,date}”,“ {2,time}”),如果没有则为null。
显然,我们可以编写自己的代码,但想知道spring是否可以做到这一点,是否有人可以提供示例或使用命名参数而不是位置参数。
干杯马克
我读过一本叫做的书Clean code.我从本书中获得的最强烈的消息之一是代码必须是可读的.我不明白为什么像F#这样的函数式语言在intellisense或类型定义中不包含函数参数名称?
相比
val copy: string -> string -> unit
Run Code Online (Sandbox Code Playgroud)
同
val copy: sourceFile:string -> destinationFile:string -> unit
Run Code Online (Sandbox Code Playgroud)
功能世界的最佳实践是什么?我们更喜欢单参数功能吗?这就是Clean code促进.或者我们是否应该使用2+参数的所有函数的记录?
我知道一个解决方法是使用static member而不是let函数,但这不是一个功能方法,是吗?
编辑:
只是为了提供更多信息:
当然还有其他人.它们只是不在类型定义中显示参数名称.
Groovy会将所有命名参数收集到一个映射中,并将其作为第一个参数传递给方法.这似乎很整洁,但在尝试使其工作后,它似乎真的无法使用.
所以问题是这样的方法:
def method(paramMap, specificVar1 = 7, specificVar2 = 14)
Run Code Online (Sandbox Code Playgroud)
当你用这样的方法调用这个方法时:
method(12, extraValue: "hello")
Run Code Online (Sandbox Code Playgroud)
你得到了很多你期望的东西:
assert 12 == specificVar1
assert 14 == specificVar2
assert [extraValue:"hello"] == paramMap
Run Code Online (Sandbox Code Playgroud)
不错,有道理.问题是,如果你认为Mapparams是可选的,你可以得到这样的值:
method(12)
Run Code Online (Sandbox Code Playgroud)
assert paramMap == 12
assert specificVar1 == 7 // default values
assert specificVar2 == 14
Run Code Online (Sandbox Code Playgroud)
那个标量应该进入特定的变量 - 而不是地图.如果我在方法中专门输入地图:
def method(Map paramMap, specificVar1 = 7, specificVar2 = 14)
Run Code Online (Sandbox Code Playgroud)
然后method(12, extraValue: "hello")像以前一样工作,但method(12)抛出一个ClassCastException.这似乎没用.有没有办法让它变得Map"粘",如果没有Map参数它就会变成空的?
是否可以在Zend Framework 2中的Select,Update或Delete查询对象中使用命名参数?例如
$myValue = 'FooBar';
$sql = new Zend\Db\Sql\Sql($adapter);
$select = $sql->select('my_table')
->where('my_column = :my_value')
->setParameter('my_value', $myValue);
Run Code Online (Sandbox Code Playgroud) named-parameters ×10
c# ×2
groovy ×2
asp-classic ×1
c#-4.0 ×1
compiler-bug ×1
f# ×1
haskell ×1
ocaml ×1
oracle ×1
php ×1
python ×1
scala ×1
spring ×1
sql ×1