Scala:是否要求函数参数是某个类的成员?
我想做一些像Scala:是否要求函数参数是某个类的成员?,scala,methods,Scala,Methods,我想做一些像 class A { def f1: Unit = ... def f2: Unit = ... } def foo(f: => Unit) { (new A).f // ??? } 其中f应该是a类的一个成员函数。我相信标准解是 def foo(f: A => Unit) { f(new A) } 并以这种方式使用它 foo(_.f1) foo(_.f2) 但现在我可以传入一个具有此签名的任意函数,这可能是不需要的。无论如何,有没有办法确保我传入的
class A {
def f1: Unit = ...
def f2: Unit = ...
}
def foo(f: => Unit) {
(new A).f // ???
}
其中f应该是a类的一个成员函数。我相信标准解是
def foo(f: A => Unit) {
f(new A)
}
并以这种方式使用它
foo(_.f1)
foo(_.f2)
但现在我可以传入一个具有此签名的任意函数,这可能是不需要的。无论如何,有没有办法确保我传入的函数是某个类的成员?好吧,如果你不介意一些曲解,你可以利用函数毕竟是一个类的事实
// abstract class MyIntToString extends (Int => String) // declare here if you want
// to use from different classes
// EDIT: f1 and f2 are now val instead of def as per comment below
// by @Régis Jean-Gilles
class A {
abstract class MyIntToString private[A]() extends (Int => String)
// if MyIntToString is declared here
// with a constructor private to the enclosing class
// you can ensure it's used only within A (credit goes to @AlexeyRomanov
// for his comment below)
val f1 = new MyIntToString {
def apply(i: Int) = i.toString + " f1"
}
val f2= new MyIntToString {
def apply(i: Int) = i.toString + " f2"
}
}
def foo(f: A#MyIntToString) = f(42) // f: MyIntToString if MyIntToString not nested in A
val a = A
现在您可以执行以下操作:
scala> foo((new A).f1)
res1: String = 42 f1
scala> foo((new A).f2)
res2: String = 42 f2
但是foo将不接受Int=>String
签名
scala> val itos = (i:Int) => i.toString
itos: Int => String = <function1>
scala> foo(itos)
<console>:11: error: type mismatch;
found : Int => String
required: MyIntToString
foo(itos)
^
scala>valitos=(i:Int)=>i.toString
itos:Int=>String=
scala>foo(itos)
:11:错误:类型不匹配;
找到:Int=>String
必需:MyIntToString
foo(itos)
^
也许您可以传递一个,然后将其称为theAInstance.f
?您可以尝试使用反射。@om nom nom我稍微修改了这个问题,以便更好地澄清。请注意,我有多个A
成员方法满足此签名(包括f1
和f2
),关键是让用户选择使用哪一个。@Ptharien的回答是的,这肯定是一个解决方案,我相信这是我们编写java或其他东西时唯一的解决方案。但是因为在scala中我们可以做foo(a:{def f1:Unit})
(这是通过java中的反射实现的,如果不允许修改现有类的话!),我只是想知道“反向”是否也是可能的。@Kane我不这么认为,因为与Objective-C不同,scala没有SEL
类型。为了防止用户创建“错误的”MyIntToString
的实例,它可能有一个私有的主构造函数。您肯定不想在每次调用时重新关联函数,所以将f1和f2转换为VAL是个好主意。@AlexeyRomanov如果我误解了您的意思,很抱歉,但我不是在实例化MyIntToString
我是在子类化它(好吧,我是在子类化它并实例化它的匿名子类)。MyIntToString可以制作成密封的
,并保存在与A
相同的文件中,如果其目的是将其使用限制在类中A@PaoloFalabella嗯,匿名子类的实例也是MyIntToString
的实例。是的,把它密封起来也行。@AlexeyRomanov你说得对,对不起。我忘了你不能只使用私有构造函数对类进行子类化。