Clojure学习1---基础语法
概述
Clojure是一种高级的,动态的函数式编程语言。 Clojure是基于LISP编程语言设计的,并且具有使其在Java和.Net运行时环境上运行的编译器。
Clojure作为一种编程语言,具有以下几种高级属性:
- 它基于LISP编程语言,使其代码语句比传统的编程语言更小。
- 它是一种函数型编程语言。
- 它专注于基本概念的不变性,你不应该对创建的对象进行任何更改。
- 它可以管理程序员的应用程序的状态。
- 它支持并发。
- 它包含现有的编程语言。 例如,Clojure可以利用整个Java生态系统来管理通过JVM运行的代码
在我们讨论Clojure之前,让我们来简单地描述LISP编程语言。 LISP有一个微小的语言核心,几乎没有语法,有一个强大的宏设施。 有了这些功能,您可以弯曲LISP以满足您的设计,而不是其他方式。 LISP已经存在了很长时间可追溯到1958年
Clojure的官方网站是 http://clojure.org/
Clojure的各种函数具体解析网站是 http://clojuredocs.org/
Clojure基础语法的网站是 https://www.braveclojure.com/introduction/
Clojure安装Emacs后的配置网站 https://github.com/purcell/emacs.d
Clojure练习题网站是 http://www.4clojure.com/
Clojure入门学习的书籍《Clojure编程》(作者 :埃默里克 翻译:徐明明 / 杨寿勋 ),这对于初学者来说比较容易理解的
Clojure有一定的基础可以看一看《Clojure编程乐趣 》
下面是个人的一些学习笔记,供大家参考学习,若有不足或者不正确的地方,请大家给我指出,互相学习。
1.定义属性
定义参数时需要引入两个包: [clojure.spec.alpha :as s]和[spec-tools.core :as st]
(ns alk-wxapi.routes.doctor[clojure.spec.alpha :as s][spec-tools.core :as st])
1.1 定义单个参数
;;定义单个参数 ,定义一个name参数,类型为string类型
(s/def ::name string?)
1.2 定义参数并且有校验
;;定义一个phone参数,类型为string,并且有校验不能为空
(s/def ::phone
(st/spec {:spec string?:description "手机号":reason 不能为空}))
1.3 body里面的多个参数,哪些为必填的,哪些为非必填,必须在前面用(s/def)定义每一个参数,再用(s/keys),
使用(s/keys :req-un [] :opt-un [] ),req-un表示必填,opt-un表示非必填,
(s/def ::id(st/spec{:spec string?:description "主键":reason "请先选择一条数据"}))...继续定义其他属性
;; ::id 这种双冒号的属性是当前这个对象中的, :base/patien-id 这种单个冒号的属性是其他对象中的属性(base中的patien-id属性)
(s/def ::body-data(s/coll-of (s/keys :req-un [::cost-date ::drug-id ::sum ::count :base/patient-id ::drug-flag]:opt-un [::id])))
2.参数接收方式
有三种:path,query,body
2.1 path接收方式
路径是哪个的参数可以用path
["/detail/:id"{:get {:summary "获取详情接口":parameters {:path (s/keys :req-un [:base/id])}:handler (fn [{{{:keys [id]} :path} :parameters}](ok (db/get-operation-cure {:id id})))}}]
2.2 body接收方式
当接口是post或者put
方式的时候,在:paramters处用body接收参数,参数特别多,在fn处可以直接用body-params表示多个参数
:put {:summary "修改商品信息";;用body接收多个参数:parameters {:body (s/keys :req-un [::product-id ::product-name]:opt-un [::product-color ::receiver-name ::receiver-tel])};;多个参数在fn中,可以直接叫body-params,而不用一个参数一个参数的写,太繁琐:handler (fn [{:keys [body-params]}](conman.core/with-transaction[*db*](db/update-product! body-params)){:status 200:body {:code 1:message "更新成功":data body-params}})}
2.3 query接收方式
当接口为get或者delete
方式的时候,用query接收参数
:get {:summary "根据id获取guestbook--设置cookies":description "查询某id的guestbook数据":parameters {:query {:id int?}}:handler (fn [{{{:keys [id]} :query} :parameters}]{:status 200:body {:data (db/get-guestbook {:id id})}:cookies {:my-cookie "123123123"}})}:put {:summary "删除检查报告":parameters {:query (s/keys :req-un [:base/id])}:handler (fn [{{{:keys [id]} :query} :parameters}](ok (conman.core/with-transaction[*db*](db/delete-examine-report! {:id id}))))}
3. 返回值
3.1只有一个返回值
:get {:summary "获取订单信息":parameters {}:handler (fn [_]{:status 200:body {:code 1:message "操作成功";;一个返回值 直接是调用获取数据的函数就可以:data (db/get-product!)}})}
3.2多个返回值:
多个返回值的时候用{}大括号包起来
["/detail"{:get {:summary "分页获取商品新":parameters {:query (s/keys :req-un [:base/page :base/size])}:handler (fn [{{{:keys [page size]}:query}:parameters}]{:status 200:body {:code 1:message "成功";;多个返回值 ,要用{}大括号包起来,一个返回值为total-elements ,一个为content:data {:total-elements (->> (db/get-products! {:count true})(map :total-elements)(first)):content (->> (db/get-products! {:page page :size size}))}}})}}]
4.函数如何传参
参数直接用{}大括号包起来 ,括号中第一个数:count为key ,第二个数为value
(db/get-products! {:count true})
(db/get-products! {:page page :size size})
5. 箭头宏
->单箭头宏和->>双箭头宏的区别
作为一个规则,当一个函数在一个奇异的主题上工作时,这个主题就是第一个参数( 比如,conj,assoc ) 。 当函数在序列主题上工作时,该主题是最后一个参数( 比如,map,filter ) 。
因此,-> 和 ->> 被记录为线程的第一个和最后一个参数,但也可以认为它们分别应用于单数或者顺序参数。
例如我们可以将一个向量看作一个奇异对象:
正确使用:作为第一个参数
(-> [1 2 3](conj 5))
=> [1 2 3 5]
错误使用:
(-> [1 2 3](conj 5))
=> [1 2 3 5]
(->> [1 2 3(conj 4])
Syntax error compiling at (form-init5287796127994100350.clj:1:1).
Unable to resolve symbol: (conj in this context
或者我们可以把它看作一个序列:
正确使用:作为最后一个参数
(->> [1 2 3](map inc))
=> (2 3 4)
错误使用
(-> [1 2 3](map inc))
Error printing return value (IllegalArgumentException) at clojure.lang.RT/seqFrom (RT.java:553).
Don't know how to create ISeq from: clojure.core$inc
有一些经验规则:
- 按照惯例,对序列进行操作的核心函数期望序列作为它们的最后一个参数。因此,管道含有map,
filter,remove,reduce,into,等通常称为->>宏。 - 另一方面,对数据结构进行操作的核心函数期望它们作为第一个参数工作的价值。这些措施包括 assoc, update, dissoc,
get和它们的 -in变种。使用这些函数转换地图的管道通常需要->宏。 - 通过Java interop调用方法时,Java对象作为第一个参数传入。在这种情况下,->例如,检查字符串是否有用是很有用的:
(-> a-string clojure.string/lower-case (.startsWith "prefix"))
还要注意更专业的互操作宏 … 和 doto。
最后,有些情况既不适用->也不->>适用。管道可以包含具有不同插入点的函数调用。在这些情况下,您需要使用as->更灵活的替代方案。as->期望两个固定的参数和可变数量的表达式。与此同时->,第一个参数是要通过以下形式进行操作的值。第二个参数是绑定的名称。在每个后续表单中,绑定名称可用于先前表达式的结果。这允许值进入任何参数位置,而不仅仅是第一个或最后一个。
具体详情请看官方文档:https://clojure.org/guides/threading_macros
6.数据结构
数据结构有list清单(…),vertor矢量[…],map地图{…},set设置#{}
list清单-------------相当于链表
vetor矢量----------相当于数组,下标长零开始
map地图------------映射,key-value
set设置-------------#{…}定义一个集合(一组唯一值)
7.注释
#_ --------------块注释, 注释某个括号内或者大括号的内容
; ----------------单行注释
{:summary "删除花费记录":parameters {:query {:id string?}};;使用#_ 注释fn这部分内容:handler #_(fn [{{{:keys [id]} :query} :parameters}](ok "删除成功"(db/update-patient-cost-deleted! {:id id})))}
Emacs工具的使用教程:
Emacs工具详细使用教程
Clojure学习1---基础语法相关推荐
- python基础语法及知识总结-Python 学习完基础语法知识后,如何进一步提高?
---4.30更新---感谢大家支持,点赞都破两千了.给大家整理出来新的资料,需要的小伙伴来自取: Python练手项目视频如下: Python自学基础知识如下: 以下为原文内容: Python 学习 ...
- idea编译的文件怎么用cmd打开_JAVA学习册|基础语法|cmd输出HelloWorld
看到这个标题,估计已经有小伙伴知识本文要讲什么了,好,下面我们就开始正文 学java最开始的地方 很多老师的书和视频中,在安装完jdk,配置好环境变量,都会带大家用记事本写一个HelloWorld,然 ...
- python学习三-基础语法
python学习三-基础语法(2019-12-24日晚) 1.源码文件 Python源码文件名通常采用小写的方式,常见的扩展名有: py:基本的源码扩展名. pyw:是另一种源码扩展名,跟py唯一的区 ...
- python语法基础学习-Python基础语法精心总结!看完都知道的可以往下继续学习了...
原标题:Python基础语法精心总结!看完都知道的可以往下继续学习了 这应该是最详细的Python入门基础语法总结! 定义变量,使用变量 1. input 用户自己输入值 2. print 打印值 可 ...
- 【python零基础入门学习】Python入门,带你快速学习Python 基础语法
ython 语言与 Perl,C 和 Java 等语言有许多相似之处.但是,也存在一些差异. 在本章中我们将来学习 Python 的基础语法,让你快速学会 Python 编程. 第一个 Python ...
- 【Drools二】打工人学习Drools基础语法
目录 0.项目搭建 1. 规则文件 1.1 构成 1.2规则体 2.基础语法 2.1 注释 2.2 Pattern模式匹配 2.3比较操作符 2.3.1 实践 2.3执行指定规则 3.Drools内置 ...
- 0基础学习Python基础语法(0)-print()与变量
文章目录 Python[人工智能]时代的立身武器 print 无引号 单引号的用法 双引号的用法 三引号的用法 转义字符 变量和赋值 变量的命名规范 下关预告 Demo 例子:打印 例子:转义字符 要 ...
- MySQL学习之基础语法详解
这篇记录一下MySQL的基础语法 DDL数据定义语言 主要是针对数据库,表,列的操作,即创建,查询,修改,删除 查询所有数据库 show databases; 创建数据库 create databas ...
- Python学习1 基础语法 数据类型 计算机基础
Python的重要性 python就业方向 Python的历史 python创造于1989年,荷兰人吉多.范罗苏姆 现在是Python3版本 09 Python的特点 1)跨平台 2)解释型语言 3) ...
最新文章
- java操作es聚合操作并显示其他字段_java使用elasticsearch分组进行聚合查询过程解析...
- 微信翻译生日快乐的代码_微信翻译出 Bug 上热搜,程序员又背锅?!
- 第一次听人用男女关系讲 N(Non-Blocking)I(进)O(出),涨姿势了
- 【年终总结】有三AI至今在人脸图像算法领域都分享了哪些内容?
- JavaScript中的对象与函数(一)
- HDU 2653 (记忆化BFS搜索+优先队列)
- WinCEService项目
- super(XXXX,self).__init__()在类中的作用
- 春节假期,我把父母家的网络整瘫了……
- pythonexcel怎么生成_Python自动生成Excel,python,excel
- python 什么是鸭子类型
- mysql捕获1300的错误_pt-osc 变更时遇到 “MySQL error 1300” 报错问题解决
- 科大讯飞 java Web api语音生成和语音识别参考
- Java坑人面试题系列: 比对while与for循环(中级难度)
- cadence导入dxf文件_Allegro PCB导入DXF文件详解
- Tensorflow③ Keras的LSTM和TF的LSTM实现的源码剖析
- 读取excel文件后计算指定行列笛卡儿积并写出
- JS实现城市选择(详细讲解,步骤清晰)
- matplotlib显示灰度图为紫色的问题
- 幼儿园计算机教案 认识画图,认识神奇画图板教案
热门文章
- 给竺老师讲解当下体育运动心理测评软件的状况
- 京东从net转Java_转!京东架构师熬夜录制,献给Java路上最最迷茫的你!赠教程...
- C#学习之帧校验序列码FCS
- python中的异常分类_列举 5 个 Python 中的异常类型以及其含义【面试题详解】
- RealLanSee 同步多端口局域网屏幕监控系统(极好用低占用!)
- 盘点游戏中那些“欺骗玩家眼睛的技巧”
- simulink中mux和function关联时信号维度报错(xxx does not fully set the dimensions of output xxx)
- (十五)集成学习(下)——蒸汽量预测
- word如何引入excel
- Hive数据仓库汽车销售分析练习题(项目)