clojure / clojurescript中单个var命名空间的命名约定是什么?

时间:2017-03-09 17:16:04

标签: clojure namespaces naming-conventions clojurescript

我经常发现自己在clojurescript中定义名称空间,其中只包含通过def或defn创建的单个var,我将在该名称空间之外使用。

这在使用时尤其常见,我在单独的文件/命名空间中定义我的组件,我只在命名空间之外使用这些单个组件。

(ns project.components.component-name)
(defn component-name ...)

所以我以这种方式导入它们,我发现它非常重复且不清楚,因为命名空间和组件都有一个名称:

project.components.component-name :as [component-name]

component-name/component-name

或inferior:refer(因为var来自另一个名称空间不太明显)

project.components.component-name :refer [component-name]

component-name

我知道在ECMAScript中有一个有用的模式:

export default function () { ... };

在Clojure中有这样的东西吗?或许也有一些既定的惯例?

以下是我最近开始使用的惯例,我对此非常不确定。

(ns project.components.component-name)
(defn _ ...)

project.components.component-name :as [component-name]

然后将其用作

component-name/_

2 个答案:

答案 0 :(得分:1)

下划线通常用于您在Clojure中不关心的值,因此我强烈建议您避免使用_作为函数名称。例如,您经常会看到如下的代码:

;; Maybe when destructuring a let. Kinda contrived example.
(let [[a _ _ d] (list 1 2 3 4)]
   (+ a d 10))

;; Quite often in a protocol implementation where we don't care about 'this'.
(defrecord Foo []
  SomeProtocol
  (thing [_ x]
    (inc x)))

在命名空间中使用单个var没有任何问题,尽管我可能只会在有合理的功能块时引入命名空间。您可以尝试使用像my-app.components这样的命名空间,在那里保留所有小位,直到它们足够大以保证专用空间。有点像这样:

(ns my-app.components
  ;; The profile stuff is really big lets say.
  (:require [my-app.components.profile :as profile]))

(defn- items->ul
  [items]
  [:ul (map #(vector :li (:text %)) items)])

(defn- render-nav
  [state]
  [:nav (-> state deref :nav-items items->ul)])

(defn- render-footer
  [state]
  [:footer (-> state deref :footer-items items->ul)])

(defn render-layout
  [state]
  [:html
   [:head [:title (:title @state)]]
   [:body
    [:main
     (render-nav state)
     (profile/render-profile (-> state deref :current-user))
     (render-footer state)]]])

答案 1 :(得分:1)

我不确定每个命名空间中的一个组件是最好的方法。这将导致 在大量的命名空间和相当多的重复。但是,这是 clojure和每个人都有不同的风格。我的方法是使用命名空间 分解功能。随着变化最简单 组件,我发现一个组件也不会使用其他组件 组件。我倾向于将所有使用的组件组合在一起 特定功能和用于大多数情况下的各种低级组件 其他组件,有/ utility /或/ base / namespace。例如,我可能 有类似的东西

project --|
          src --|
                my-app --|
                         core.cljs
                         interface --|
                                     base.cljs
                                     navbar.cljs
                                     sidebar.cljs
                                     tabber.cljs

在每个名称空间中,可能有多个组件。其中一些可能 被定义为该命名空间的私有,其他是其中的入口组件 由core.cljs引用。我发现名称空间要求部分也不会得到 大或重复,我不需要在不同的文件中跳转 因人而异。