2016-08-02 93 views
1

Wie würde ich dieses Muster arbeiten lassen? func() kann nicht kompiliert werden. Ich verstehe das Problem mit diesem Setup, aber was ist ein Muster, das im Grunde das erreichen könnte?scala polymorphe Art für Rückgabewert

class A() { 
    val a: Int = 123 
    val b: String = "xxx" 
} 

def func[T](key: String, a: A): T = { 
    if  (key == "a") a.a  // would make T an Int 
    else if (key == "b") a.b  // would make T a String 
} 

val a = new A() 
func[Int]("a", a) 
func[String]("b", a) 
+1

Was meinst du mit "dies im Grunde erreichen"? Dies ist kein Muster, es ist eine Unmöglichkeit. –

Antwort

3

Ich bin mir nicht ganz sicher, was Sie anstreben, aber ein paar Möglichkeiten.

class A() { 
    val a: Int = 123 
    val b: String = "xxx" 
} 

def func[T : Manifest](a: A) = implictly[Manifest[T]] match { 
    case implicitly[Manifest[Int]]) => a.a 
    case implicitly[Manifest[String]) => a.b 
} 

val a = new A() 
func[Int](a) 
func[String](a) 

oder

class A() { 
    val a: Int = 123 
    val b: String = "xxx" 
} 

val aKey = (_: A).a 
val bKey = (_: A).b 

def func[T](key: A => T, a: A) = key(a) 

val a = new A() 
func(aKey, a) 
func(bKey, a) 

oder sogar mit Shapeless,

import shapeless._ 
import syntax.singleton._ 
import record._ 

val a = ("a" ->> 123) :: ("b" ->> "xxx") :: HNil 

a("a") // typed as an Int 
b("b") // typed as a String 
2

Vielleicht ist das nah dran, wonach Sie suchen?

class A() { 
    val a: Int = 123 
    val b: String = "xxx" 
} 

def func(key: String, a: A): Either[Int,String] = { 
    if (key == "a") Left(a.a) 
    else   Right(a.b) 
} 

val a = new A() 
func("a", a) // Left(123) 
func("b", a) // Right("xxx")