Chúng tôi thường cần phải đi qua thông tin ngữ cảnh mã như người dùng đang thực hiện hành động. Chúng tôi sử dụng ngữ cảnh này cho nhiều thứ khác nhau như kiểm tra ủy quyền. Trong những trường hợp này, các giá trị tiềm ẩn có thể chứng minh là rất hữu ích để giảm bớt mã tấm nồi hơi.Các giá trị trích xuất được trích xuất trong kết hợp mẫu?
Hãy nói rằng chúng tôi có một bối cảnh đơn giản thực hiện mà chúng ta vượt qua xung quanh: case class EC(initiatingUser:User)
Chúng ta có thể có lính gác tiện dụng:
def onlyAdmins(f: => T)(implicit context:EC) = context match{
case EC(u) if(u.roles.contain(Role.ADMIN)) => f
case _ => throw new UnauthorizedException("Only admins can perform this action")
}
val result = onlyAdmins{
//do something adminy
}
thời gian gần đây tôi thấy mình cần phải làm điều này khi làm việc với các diễn viên Akka nhưng họ sử dụng kết hợp mẫu và tôi chưa tìm ra cách tốt để làm cho implic hoạt động tốt với các bộ giải nén.
Trước tiên, bạn sẽ cần phải vượt qua bối cảnh với mỗi lệnh, nhưng đó là dễ dàng:
case class DeleteCommand(entityId:Long)(implicit executionContext:EC)
//note that you need to overwrite unapply to extract that context
Nhưng nhận chức năng trông như thế này:
class MyActor extends Actor{
def receive = {
case DeleteCommand(entityId, context) => {
implicit val c = context
sender ! onlyAdmins{
//do something adminy that also uses context
}
}
}
}
Sẽ đơn giản hơn nhiều nếu biến chiết xuất có thể được đánh dấu là tiềm ẩn nhưng tôi chưa thấy tính năng này:
def receive = {
case DeleteCommand(entityId, implicit context) => sender ! onlyAdmins{
//do something adminy (that also uses context)
}
}
Ar e bạn biết về bất kỳ cách thay thế mã hóa này để nó làm giảm mã boilerplate?
Bạn có thể quan tâm này: http://stackoverflow.com/questions/6156656/how-to-pattern-match-a-class-with-multiple-argument-lists – gzm0
này nghe có vẻ giống như những gì GADTs làm trong Haskell, nếu bạn xem xét sự giống nhau của bối cảnh typeclass đối với implicits. Nó cũng có thể cung cấp một cách nguyên tắc hơn để thực hiện mô hình giống như GADT phù hợp trong Scala hoạt động tốt. –