我有一个特点:
trait OAuthService {
def sendWithAuthorizationQueryParams[A](request: OAuthRequest)(implicit unmarshaller: Unmarshaller[ResponseEntity, A]): Future[A] = {
val httpRequest = request.toHttpRequestWithAuthorizationQueryParams
sendAndReceive(httpRequest, request.signature)
}
def sendWithAuthorizationHeader[A](request: OAuthRequest)(implicit unmarshaller: Unmarshaller[ResponseEntity, A]): Future[A] = {
val httpRequest = request.toHttpRequestWithAuthorizationHeader
sendAndReceive(httpRequest, request.signature)
}
protected def sendAndReceive[A](httpRequest: HttpRequest, id: String)(implicit unmarshaller: Unmarshaller[ResponseEntity, A]): Future[A]
}
我正在创建一个子类:
class StreamingOAuthService()(implicit val actorPlumbing: ActorPlumbing) extends OAuthService {
private val log = LoggerFactory.getLogger(getClass())
override protected def sendAndReceive[A](httpRequest: HttpRequest, id: String)(implicit unmarshaller: Unmarshaller[ResponseEntity, A]) = {
log.debug(s"Http request: {}.", httpRequest)
import actorPlumbing._
val host = httpRequest.uri.authority.host.address()
val connectionFlow: Flow[HttpRequest, HttpResponse, Future[OutgoingConnection]] = Http().outgoingConnectionTls(host)
Source.single(httpRequest)
.via(connectionFlow)
.runWith(Sink.head)
}
}
在StreamingOAuthService
中,我想将泛型类型卡住为ResponseEntity
。换句话说,我想指定 StreamingOAuthService
方法支持的唯一类型是 ResponseEntity
。如图所示,StreamingOAuthService.sendAndReceive
无法编译,因为返回类型是 Future[ResponseEntity]
而不是 Future[A]
,如指定的特质。
最佳答案
我对之前的答案进行了更多思考,即使在多类型形式中,它仍然不是很令人满意,因为您需要定义所有类型 A
, B
等您想要使用的基类的任何实例,然后该子类只能为每个方法接受这些类型。
类型运算符(广义类型约束)看起来提供了更好的选择:
trait Base {
type T
def fun1[A](input: String)(implicit tp: A <:< T): A
def fun2[A](input: Int)(implicit tp: A <:< T): A
}
class RestrictedSub extends Base {
override type T = Double
def fun1[A](input: String)(implicit tp: A <:< T): A = {
...
}
def fun2[A](input: Int)(implicit tp: A <:< T): A = {
...
}
}
对于任何方法的调用,编译器都可以提供合适的隐式 <:<[A,T]
(通常写作 A <:< T
,类似于二元运算符)当且仅当 A
是 T
的子类型,因此在编译时应禁止任何不适当的调用。
对于不受限制的子类(特征伴生对象中工厂方法的一个很好的候选者),类型 T
可以设置为Any
或AnyRef
视情况而定。
不过,我确实注意到,我还没有尝试使用它来构建具有隐式 Unmarshaller
的特征的完整版本。和 Future
返回类型,这可能会使正确的解决方案变得复杂。
关于Scala 类型 : How to Restrict the Generic Type of a Subclass?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32839272/