Без шумовой обработки JSON с Scala
Я прихожу из домена dotnet, но в последнее время смотрю на возможности альтернативных языков программирования. Ничего серьезного, просто несколько бит тут и там. Недавно я обнаружил Scala, и я очень очарован этим. Несмотря на недетерминированное вмешательство, я провел несколько промежуточных проверок вещей, которые важны для меня на С#, и я чувствую себя довольно удовлетворенными: функциональные понятия - тик, ad-hoc полиморфизм - тик, аннотации - тик, отражение и codegen - тик.
Теперь я думаю о том, как можно запрограммировать аналог библиотеки обработки JSON, который я реализовал в С# 4.0, с помощью DLR и "динамического" синтаксического сахара. Вот набор функций, который я ищу:
- Удобный просмотр и построение исходного JSON.
- Автоматическое преобразование между JSON и собственными объектами/коллекциями (в его общем виде проблема неразрешима, хотя можно определить соглашения, которые будут работать 95% времени - и это хорошо для меня).
Новые возможности С# 4.0 рока здесь, поскольку они позволяют мне переопределять доступ к члену и набирать типы для выполнения полностью настраиваемой логики (если переменная в С# 4.0 вводится как "динамическая", то все, что вы делаете с ней, будет скомпилировано в вызовы программируемым методам с разумным поведением по умолчанию - см. DynamicMetaObject.BindXXX методы в MSDN для получения дополнительной информации). Например. У меня есть избыточные типы прикладов для сериализации/десериализации объектов .NET и доступа членов для управления сырым JSON, чтобы я мог написать следующий код:
var json = Json.Get("http://some.service");
if (json.foo) Console.WriteLine((Foo)json.foo);
json.bars = ((List<Bar>)json.bars).DoSomething();
Конечно, это не идеально, поскольку динамическое связывание в С# 4.0 имеет проблемы с методами расширения и типом вывода, и, кроме того, код по-прежнему чувствует себя довольно тяжеловесным. Но в любом случае это намного лучше, чем использование всех этих (JsonObject) json [ "quux" ]) [ "baz" ] Я использовал в С# 3.5.
Некоторые базовые исследования показывают, что Scala не имеет выделенных языковых функций, которые поддерживают позднюю привязку. Тем не менее, существует так много трюков, что, возможно, их можно использовать вместе, чтобы создать терпимую эмуляцию кода, показанного выше (или даже лучше - я почти уверен, что это возможно). Не могли бы вы посоветовать мне что-то здесь?
Ответы
Ответ 1
Полезной библиотекой JSON для Scala является lift-json, которая является автономным компонентом платформы веб-сайтов Lift.
https://github.com/lift/framework/tree/master/core/json
Он поддерживает извлечение классов, разбор и DSL для создания JSON.
На странице, с которой я связан, есть полный учебник, поэтому я не буду просто копировать и вставлять его.
Ответ 2
Вам обязательно нужно взглянуть на sjson. Здесь → sjson on github
Я использую реализацию на основе класса типа, которую вы можете просмотреть здесь → несколько примеров
Если у вас есть прогулка по коду, есть несколько действительно интересных трюков scala. Это должно дать вам то, что вы ищете в отношении № 2. SJSON wraps dispatch-json, который, как я полагаю, обеспечивает интеграцию в lift-json (упоминалось выше). Оба диспетчера-json/lift-json должны дать вам то, что вы ищете в # 1. Для чего он стоит, я использовал sjson в большом проекте и плавно. И джентльмен, стоящий за проектом, был довольно изумительным и очень хорошо поддерживает проект.
Ответ 3
Я плавал между lift-json
и различными вариантами sjson
(например, dabasishg/sjson), а в последнее время Jerkson
(a Scala обертка на Jackson).
Для целей сериализации объектов и десериализации я продолжаю находить Jerkson
, чтобы потребовать минимальную настройку, чтобы выполнить задание, например, я только что кодировал простую сериализацию объектов с помощью case class
, которая выглядит как это:
import org.joda.time.LocalDate
case class UserStatus(subscriptionEndDate: LocalDate = null)
У меня были различные ошибки как с lift-json
, так и с sjson
, но Jerkson
сработало с:
import com.codahale.jerkson.Json
val jsonString = Json.generate(statusObject)
и
val newObject = Json.parse[UserStatus](jsonString)
Ответ 4
Как указывали другие, есть много вариантов. Помимо упомянутых выше, большинство библиотек обработки Java JSON также должны работать с Scala с различным уровнем удобства (для) для языков Java без Java (например, Scala, Clojure, Groovy).
Наиболее эффективными с точки зрения привязки данных являются Jackson, GSON и FlexJSON. Одна из возможностей - проверить их и посмотреть, можете ли вы помочь улучшить взаимодействие - Scala, например, имеет ряд "экзотических" типов данных, которые могли бы выиграть от явной обработки (над и над обработкой "стандартных" java-объектов, которые libs).
Ответ 5
Если вы хотите что-то действительно динамичное в scala, вот оно: http://www.scala-lang.org/api/current/scala/Dynamic.html
A marker trait that enables dynamic invocations. Instances x of this trait allow calls x.meth(args) for arbitrary method names meth and argument lists args. If a call is not natively supported by x, it is rewritten to x.applyDynamic("meth", args).
As of scala 2.9, scalac must receive the -Xexperimental optional for Dynamic to receive this treatment.
Теперь это экспериментальная функция, и не такая сильная, как .NET DLR.
Casbah пробовал драйвер scala -mongodb.
Ответ 6
достаточно интересный код для этого в scala больше связан с Java. Ни один из этих ответов не дает бесшумного решения, такого как библиотека Java Jackson, за исключением Джерксона, который обертывается вокруг Джексона.
ObjectMapper mapper = new ObjectMapper(); // can reuse, share globally
User user = mapper.readValue(new File("user.json"), User.class); //to parse
mapper.writeValue(new File("user-modified.json"), user); //to produce