将变量参数数据类型传递给scala方法

时间:2017-01-23 16:54:46

标签: scala

我想在scala中创建一个方法/函数,它可以接受string或int类型的变量参数,并返回String或Int类型的结果。

def Hello(name: String, Param: int*/string*): Int/String= {

var index = 0

while(index < Param.length) {

var n = name

var ar = Param(index)

if ( n.equals(ar) ) return Param(index + 1) 

else index = index + 1

}

return Param(index.length -1)

}

如果我们调用Hello函数,那么它应该返回如下所示的结果。

val Res1 = Hello("Jack", "rakesh", 1, "Jack", 2, "No one") 

println(Res1)

=> this should return value 2

val Res2 = Hello("ABC", "rakesh", 1, "Jack", 2, "Vik", 3, "ram", 4, "No one") 

println(Res2)

=> this should return value "No one"

4 个答案:

答案 0 :(得分:1)

这会对你有所帮助

def Hello( name: String,args: Any* ) = {

      val index = args.indexOf(name)
      if(index == -1)
        args(args.length - 1)            
      else
      args(index + 1)

 } 

答案 1 :(得分:1)

使用Any应该有效:

def hello(name: Any, param: Any*): Any= {
    var list = param.dropWhile(_ != name)
    list.drop(1).headOption.orElse(param.lastOption).getOrElse("")
}

根据您希望的类型安全性,您可以尝试使用泛型或其他方法来限制使用的类型。或者您只需模式匹配响应类型:

hello("ABC", "rakesh", 1, "Jack", 2, "Vik", 3, "ram", 4, "No one") match {
  case i: Int => println("Got a int:" + i)
  case s: String=> println("Got a string:" + s)
}

答案 2 :(得分:1)

我相信,您想要实现的目标是在varargs中获取String元素的索引(如果从1开始计数),或者返回"No one"。无需将索引传递给方法。你可以这样做:

def hello(name: String, params: String*): Any = {
  val idx = params.indexOf(name)
  if (idx != -1) idx + 1 else "No One"
}

不幸的是this

def Hello(name: String, args: Any* ) = {
  val index = args.indexOf(name)
  if(index == -1)
    args(args.length - 1)
  else
    args(index + 1)
}

this

def hello(name: String, param: Any*): Any= {
  var index = 0
  while(index < param.length) {
    var n = name
    var ar = param(index)
    if ( n.equals(ar) ) return param(index + 1)
    else index = index + 1
  }
  param(index -1)
}

被破坏,因为如果你试图找到"No one"的索引,它们会抛出异常,因为index + 1将等于数组的大小。最好将Scala中的内容与==进行逻辑相等比较。

但最好不要返回Any,而是返回Option[Int]

def hello(name: String, params: String*): Option[Int] =
  Option(params.indexOf(name)).filter(_ != -1).map(_ + 1)

那么你可以像这样使用它:

val message1 = hello("Jack", "rakesh" ,"Jack").getOrElse("No one")
val message2 = hello("ABC", "rakesh", "Jack", "Vik", "ram").getOrElse("No one")

回答评论:

  

我想知道如何将混合数据类型传递给&#34; param&#34;。

最简单的方法是将它们全部放在Any

类型中
  

并且还将字符串或整数作为返回类型

同样,将返回类型定义为Any

这里唯一的小问题是不会对其他类型进行编译时检查。例如。有人可能会将Boolean或任何复杂对象与StringInt一起传递给您的函数。但您可以在运行时检查它或使用类型来限制它们。我不知道你的要求,也许这对你有利。

如果Any没问题,我会这样解决:

def Hello(name: Any, params: Any*): Any = Option(params)
  .withFilter(_.nonEmpty)
  .map(_.indexOf(name))
  .filter(i => i != -1 && i < params.length - 1)
  .map(i => params(i + 1))
  .getOrElse("No one")

或者,如果您可以认为,params永远不会为空,您必须使用最后一个参数作为默认参数,而不仅仅是硬编码"No one"

def Hello(name: Any, params: Any*): Any = Option(params)
  .withFilter(_.nonEmpty)
  .map(_.indexOf(name))
  .filter(i => i != -1 && i < params.length - 1)
  .map(i => params(i + 1))
  .getOrElse(params.last)

请注意针对"No one"攻击的检查:i < params.length - 1。 请注意,name现在也是Any类型。

现在,即使您将"No one"作为name传递,Option也会评估为None感谢过滤器,getOrElse会给您

答案 3 :(得分:1)

你的整个方法都是错误的,但这是如何以类型安全的方式完成的。

sudo tlmgr install titlesec

用法:

def Hello(name: String, param: Either[Int,String]*): Either[Int,String] = {
  param.sliding(2,2)
       .find(_(0).fold(_ => false, _ == name))
       .fold(param.last)(_(1))
}

但最好从头开始重新考虑它。