Clojure Java взаимодействия для com.google.cloud.storage.StorageImpl
Попытка взаимодействия с Java с помощью https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java#L139 - create
метод с байтовым массивом.
Я имею в своем ответе:
user=> (->> s r/reflect :members
(filter #(instance? clojure.reflect.Method %))
(filter #(:public (:flags %)))
(filter #(= (str (:name %)) "create"))
(print-table [:name :flags :parameter-types]))
| :name | :flags | :parameter-types |
|--------+---------------------+------------------------------------------------------------------------------------------------------------|
| create | #{:varargs :public} | [com.google.cloud.storage.BlobInfo byte<> com.google.cloud.storage.Storage$BlobTargetOption<>] |
(Есть и другие, но это кажется наиболее актуальным.)
Также:
user=> s
#object[com.google.cloud.storage.StorageImpl 0x57fb59c8 "com.google.cloud.storage.StorageImpl@57fb59c8"]
user=> blob-info
#object[com.google.cloud.storage.BlobInfo$BuilderImpl 0x1e8ce729 "com.google.cloud.storage.BlobInfo$BuilderImpl@1e8ce729"]
user=> b
#whidbey/bin "SEVZIE1ZIEdVWQ==“
Но когда я иду, чтобы позвонить .create
, Я получил:
user=> (.create s blob-info (bytes b))
java.lang.IllegalArgumentException: No matching method create found taking 2 args for class com.google.cloud.storage.StorageImpl
Если я попытаюсь добавить nil
в качестве третьего аргумента я получаю ту же ошибку с 3 args
,
Я что-то упускаю здесь очевидное? Спасибо!
Редактировать: Как обрабатывать аргументы Java переменной длины в clojure? был очень похож и более универсален (что хорошо). Этот вопрос оказался конкретным вопросом об одном конкретном create
подпись функции.
2 ответа
В конечном итоге ответ (из Seancorfield на Clojurians провисать), что blob-info
был BuilderImpl
внутренний класс и должен быть фактическим BlobInfo
, Код, который работает:
(defn get-storage []
(-> (StorageOptions/getDefaultInstance)
(.getService)))
(defn get-blob-info [bucket storage-key]
(let [content-type "text/plain"
blob-id (BlobId/of bucket storage-key)
builder (doto
(BlobInfo/newBuilder blob-id)
(.setContentType content-type))]
(.build builder)))
(defn upload-str [bucket storage-key str-to-store]
(let [storage (get-storage)
blob-info (get-blob-info bucket storage-key)
byte-arr (.getBytes str-to-store)]
(.create storage
blob-info
byte-arr
(into-array Storage$BlobTargetOption []))))
Не требуется указывать тип подсказки - просто нужно, чтобы типы правильно выстроились.
Я не уверен (bytes b)
правильный синтаксис (что такое #whidbey/bin
???).
Может быть попробовать
(byte-array [1 2 3])
или похожие. Вы также можете попробовать набрать текст в параметре:
(.create s
blob-info
^"[B" (byte-array [1 2 3]) ; type-hinted param
)
Обновить
Вот пример подсказки типа, который, я думаю, вам нужен:
(let [byte-array-obj (byte-array [1 2 3])
sss (java.util.Arrays/toString ^"[B" byte-array-obj) ]
(spyxx byte-array-obj)
(spyx (type byte-array-obj))
(spyx (aget byte-array-obj 2))
(spyx sss))
с результатом:
byte-array-obj => <#[B #object["[B" 0x26071f95 "[B@26071f95"]>
(type byte-array-obj) => [B
(aget byte-array-obj 2) => 3
sss => "[1, 2, 3]"
Обратите внимание, что Clojure имеет простой способ ввода подсказок, не прибегая к java-native "[B"
синтаксис строки:
(java.util.Arrays/toString ^"[B" byte-array-obj) ; type hint using a string
(java.util.Arrays/toString ^bytes byte-array-obj) ; Clojure "build-in" type hint
оба из которых эквивалентны.