Я хотел бы знать, какая лучшая Scala имитация Groovy оператор безопасного разыменования (?.) или на по крайней мере, некоторые близкие альтернативы?
Я обсудил это в беседе на блоге Daniel Spiewak, но как открыть его до StackOverFlow...
Ради каждого времени, вот исходный ответ Дэниела, мой счетчик и его второй ответ:
@Antony
Собственно, я смотрел на это первый. Вернее, я пытался реплицировать Ragenwalds andand "оператор" с земли Руби. Проблема это, это немного сложно сделать без прокси. Рассмотрим следующее выражение (используя Rubys и, и то же самое с Groovy s):
test.andand(). ЙоЗотеЬЫпд()
Я мог бы создать неявное преобразование из Any = > некоторый тип, реализующий andand(), но там, где магия останавливается. Независимо от того, значение равно null или нет, Метод doSomething() будет по-прежнему выполнить. Поскольку он должен выполнить какой-либо целевой тип безопасным образом, что потребует осуществления прокси-сервера байт-кода, который был бы flaky и weird (проблемы с аннотации, окончательные методы, конструкторы и т.д.).
Лучшей альтернативой является возвращение к источник вдохновения для обоих и, а также безопасный Groovy s оператор разыменования: монадическая карта операция. Ниже приведено несколько Scalaсинтаксис, который использует Option для реализации шаблон:
val something: Option [String] =...// предположительно, может быть либо Некоторое (...), либо Отсутствует
val length = something.map(_. length)
После этого
length
либо будет Некоторые (str.length) (где str - Объект String, содержащийся в Option) или None. Это как раз то, как оператор безопасного разыменования работает, за исключением того, что он использует null, а не типовая монада.Как указывалось выше, мы могли бы определить неявное преобразование из некоторого типа T = > Option [T], а затем отобразите в этом моды, но некоторые типы уже определенная карта, поэтому она не была бы очень полезно. В качестве альтернативы я мог бы реализовать что-то похожее на карту, но с отдельным именем, но любым способом будет реализован, он будет полагаться на функции более высокого порядка, а не простой цепной звонок. Это кажется просто характер статически типизированного языков (если у кого есть способ это, не стесняйтесь исправлять меня).
Даниэль Спивак. Понедельник, 7 июля 2008 года. 1:42 вечера
Мой второй вопрос:
Спасибо за ответ Дэниел относительно?. Думаю, я пропустил это! я думаю, я понимаю, что ты предлагая, но как насчет чего-то например, если вы не имеете контроль над источниками:
company?.getContactPerson?.getContactDetails?.getAddress?.getCity
Скажите, что это java bean, и вы не можете пойти и измените возвращаемые значения на Что-то [T] - что мы можем там сделать?
Энтони Стаббс Вторник, 21 июля 2009 г. в 8:07 вечера oh gosh - нормально перечитывать это то, где вы предлагаете неявное преобразование из T в Опция [T] правильно? Но не могли бы вы быть в состоянии объединить его, как что? Вам все еще нужна карта? хмм....
var city = company.map(_.getContactPerson.map(_.getContactDetails.map(_.getAddress.map(_.getCity))))
?
Энтони Стаббс Вторник, 21 июля 2009 г. в 20:10
Его второй ответ:
@Antony
Мы не можем действительно многое сделать в случай компании?.getContactPerson, и т.д. Даже если предположить, что это действительно Scala, нам все равно понадобится способ предотвращения последующих вызовов в цепь. Это невозможно, если бы не используя значения функций. Таким образом, что-то вроде карты действительно единственное вариант.
Неявное преобразование в параметр не было бы плохо, но, делая вещи неявные, обходили некоторые из защита системы типов. Лучший способ сделать это использовать для понимания с опцией. Мы можем делать карты и flatMap, но гораздо приятнее магический синтаксис:
for {
c < - company
person <- c.getContactPerson
details <- person.getContactDetails
address <- details.getAddress
} yield address.getCity
Даниэль Спивак Вторник, 21 июля 2009 года в 21:28
P.s. если Даниэль отправит свои исходные ответы в своем блоге в качестве ответов, я отредактирую вопрос, чтобы удалить их для системы.