Tôi muốn biết những gì giả Scala tốt nhất của Groovy safe-dereference operator (?.), hoặc ít nhất một số lựa chọn thay thế gần?Giả lập Scala tốt nhất của nhà điều hành an toàn-dereference của Groovy (?.)?
Tôi đã discussed it breifly trên blog Daniel Spiewak 's, nhưng muốn mở nó lên để Stackoverflow ...
Vì lợi ích của thời gian của mọi người, đây là phản ứng của Daniel ban đầu, truy cập của tôi, và phản ứng thứ 2 của mình :
@Antony
Actually, I looked at doing that one first. Or rather, I was trying to replicate Ragenwald’s andand “operator” from Ruby land. The problem is, this is a bit difficult to do without proxies. Consider the following expression (using Ruby’s andand, but it’s the same with Groovy’s operator):
test.andand().doSomething()
I could create an implicit conversion from Any => some type implementing the andand() method, but that’s where the magic stops. Regardless of whether the value is null or not, the doSomething() method will still execute. Since it has to execute on some target in a type-safe manner, that would require the implementation of a bytecode proxy, which would be flaky and weird (problems with annotations, final methods, constructors, etc).
A better alternative is to go back to the source of inspiration for both andand as well as Groovy’s safe dereference operator: the monadic map operation. The following is some Scala syntax which uses Option to implement the pattern:
val something: Option[String] = … // presumably could be either Some(…) or None
val length = something.map(_.length)
After this,
length
either be Some(str.length) (where str is the String object contained within the Option), or None. This is exactly how the safe-dereferencing operator works, except it uses null rather than a type-safe monad.As pointed out above, we could define an implicit conversion from some type T => Option[T] and then map in that fashion, but some types already have map defined, so it wouldn’t be very useful. Alternatively, I could implement something similar to map but with a separate name, but any way it is implemented, it will rely upon a higher-order function rather than a simple chained call. It seems to be just the nature of statically typed languages (if anyone has a way around this, feel free to correct me).
Daniel Spiewak Monday, July 7, 2008 at 1:42 pm
câu hỏi thứ 2 của tôi:
Thanks for the response Daniel regarding ?. I think I missed it! I think I understand what you’re proposing, but what about something like this, assuming you don’t have control over the sources:
company?.getContactPerson?.getContactDetails?.getAddress?.getCity
Say it’s a java bean and you can’t go in and change the return values to Something[T] - what can we do there?
Antony Stubbs Tuesday, July 21, 2009 at 8:07 pm oh gosh - ok on re-read that’s where you’re proposing the implicit conversion from T to Option[T] right? But would you still be able to chain it together like that? You’d still need the map right? hmm….
var city = company.map(_.getContactPerson.map(_.getContactDetails.map(_.getAddress.map(_.getCity))))
?
Antony Stubbs Tuesday, July 21, 2009 at 8:10 pm
phản ứng thứ 2 của ông:
@Antony
We can’t really do much of anything in the case of company?.getContactPerson, etc… Even assuming this were valid Scala syntax, we would still need some way to prevent the later calls in the chain. This is not possible if we’re not using function values. Thus, something like map is really the only option.
An implicit conversion to Option wouldn’t be bad, but by making things implicit, we’re circumventing some of the protection of the type system. The best way to do this sort of thing is to use for-comprehensions in concert with Option. We can do map and flatMap, but it’s much nicer with magical syntax:
for {
c < - company
person <- c.getContactPerson
details <- person.getContactDetails
address <- details.getAddress
} yield address.getCity
Daniel Spiewak Tuesday, July 21, 2009 at 9:28 pm
T.B. nếu Daniel đăng câu trả lời gốc của mình lên blog của mình làm câu trả lời, tôi sẽ chỉnh sửa câu hỏi để xóa chúng vì lợi ích của Hệ thống.
Xem thêm http://stackoverflow.com/questions/1364361/how-to-write-a-proper-null-safe-coalescing-operator-in-scala –