Slick把数据库编程融入到scala编程中,编程人员可以不需要编写SQL代码。我把Slick官方网站上Slick3.1.1文档的Slick介绍章节中的一些描述和例子拿过来帮助介绍Slick的功能。...下面是Slick数据库和类对象关系对应的一个例子: 1 import slick.driver.H2Driver.api._ 2 object slickIntro { 3 case class...现在这个coffees就是scala里的一个对象,但它代表了数据库表。...Slick把Query编写与scala语言集成,这使编程人员可以用熟悉惯用的scala来表述SQL Query,直接的好处是scalac在编译时就能够发现Query错误: 1 //coffees.map...具体实现方式是利用freemonad(DBIOAction类型就是个freemonad)的延迟运算模式,将DBIOAction的编程和实际运算分离,在DBIOAction编程过程中不会产生副作用(side-effect
看完Slick官方网站上关于Slick3.1.1技术文档后决定开始动手建一个项目来尝试一下Slick功能的具体使用方法。我把这个过程中的一些了解和想法记录下来和大家一起分享。...Slick是集成jdbc的更高层的Query编程语言,可以通过jdbc的url、DataSource等来指定目标数据库类型及相关的参数。...对应Slick中的具体函数有: val db = Database.forConfig("mydb") val db = Database.forURL("jdbc:h2:mem:test1;DB_CLOSE_DELAY...除h2之外其它都没进行测试验证,具体配置参数和方法要参考数据库开发商提供的技术文档。我在这个示范里选用了h2配置:它会在我的用户根目录下创建一个slickdemo.h2.db数据库文件。...使用了case class AlbumModel作为库表字段对应模版。这样一是可以规范代码,再就是如果遇到一个宽表有很多列的话可以节省许多重复铺垫及避免无谓错误。
在这篇讨论里我想以函数式思考模式来加深了解Slick。我对fp编程模式印象最深的就是类型匹配:从参数类型和返回结果类型来了解函数功能。...表行定义操作方法基本都在slick.lifted.AbstractTable里、表属性定义在slick.model命名空间里、而大部分的帮助支持函数都在slick.lifted命名空间的其它对象里。...所有Query对象里提供的函数TableQuery类都可以调用。...在slick.profile.RelationalProfile.TableQueryExtensionMethods里还有专门针对TableQuery类型的函数如schema等。...上面的DriverAction是DBIOAction的子类。因为DBIOAction是个free monad,所以多个DBIOAction可以进行组合,而在过程中是不会立即产生DBIO副作用的。
在Slick官方文档中描述:连接后台数据库后,需要通过定义Projection,即def * 来进行具体库表列column的选择和排序。...也可以说是与定义column的类参数进行对应。...造成的后果是返回的结果行不含字段名,只有字段位置。使用这样的行数据很容易错误对应,或者重复确认正确的列值会影响工作效率。...如果返回的结果类型是Seq[Person]这样的话:Person是个带属性的对象如case class,那么我们就可以通过IDE提示的字段名称来选择字段了。...现在Table的类型参数必须是Person。上面的Projection都是对Table默认Projection的示范。
先介绍一下slick,它是一款开源的scala语言数据库处理框架,官网http://slick.lightbend.com/。...字段,并为主键及自动增长,类型为Int;name对应表中name字段,类型为String;geom对应空间字段geom,类型为Point(空间字段类型可以直接设置为Geometry);def * 表示三个字段的组合...,首先引入上面driver中定义的api,之后定义实体类继承自Table对象,其泛型即为def *中组合类型,并且二者顺序必须完全一致。...其中ConnDatabase是上文我们写好的数据库连接类,主要目的在于得到其中的db对象,所以必须先执行connectDb函数,传入数据库参数。...对数据进行空间操作: geotrelis.slick支持将scala的空间操作转换为PostGIS的空间函数,如下: def getGeomWKTData { val q = for {
我认为这是一项非常好的技术,它可以满足构建微服务所需的所有基本要求: 易于实现 快速 健壮性 很好的支持和文档记录 在数据方面,我选择了Slick作为库,将数据库交互和FlyWay抽象为数据库迁移框架。...),它将验证消费者(Consumer)是否将按照协议中的规定进行要求。...WordSpec,ScalatestRouteTest,Matchers,MockFactory,BeforeAndAfterAll和定义应用程序的路由的性状:Routes 当然它不会编译也不会传递,因为还没有实现...最后一条指令是定义TableQuery对象,该对象对于该表执行任何类型的查询都是必需的。...你可以看到dao在trait中被实例化,如果逻辑变得更复杂,我建议将它作为必需的参数(隐式或类属性)移动,以便从外部注入它们。
我认为这是一项非常好的技术,它可以满足构建微服务所需的所有基本要求: 易于实现 快速 健壮性 很好的支持和文档记录 在数据方面,我选择了Slick作为库,将数据库交互和FlyWay抽象为数据库迁移框架。...,ScalatestRouteTest,Matchers,MockFactory,BeforeAndAfterAll和定义应用程序的路由的性状:Routes 当然它不会编译也不会传递,因为还没有实现,所以让我们定义我们的路由...最后一条指令是定义TableQuery对象,该对象对于该表执行任何类型的查询都是必需的。...您可以在官方文档中找到更多关于如何在Slick中实现实体和DAO的示例和信息。...你可以看到dao在trait中被实例化,如果逻辑变得更复杂,我建议将它作为必需的参数(隐式或类属性)移动,以便从外部注入它们。
导致学习过程特别的痛苦 所以我想把其中一些重要的东西记录下来,让和我一样正在学习scala的同学能多一些思考,少走一些弯路。...Scala是一门静态类型,结合了面向对象和函数式的,拥有强大的类型系统的语言。而Groovy是一门同时提供了动态类型和静态类型,基本兼容Java语法的语言。 这两者的特性、适合场景都不一样。...然而这些库在scala中,要么用起来非常别扭,要么有一些奇怪的问题。而Scala原生的库,比如squeryl,slick等,都有“多利用类型系统,少做魔术”的追求,所以用起来总是不那么好用。...但是混用的过程还是比较痛苦的: 很多类,特别是集合类,Java与Scala各有一套,我们需要不停转换 Java与Scala类型系统不完全相同,有时候会遇到奇怪的编译错误 有些java库会对javabean...比如,关于函数式编程,有人说它有两个重要的特点: 追求不变性和无副作用 函数作为一等公民,它可以当作值一样定义、传递 然后我们想,我已经做到了尽量用val不用var,也不在方法里中做一些有副作用的操作
我们经常对参数名为 id 的类型编码,但是这就是一些产生小 bug 的原因,即当一个函数有多个标识符作为参数的时候,一些调用就会弄混参数顺序。...同时 map 的零值有个严重的缺陷:它可以查询,但在 map 中存储任何数据都有导致 panic 异常: ? 当结构具有 map 字段时,就要当心了,因为在向其添加条目之前必须对其进行初始化。...事实上,json 解码器有一个会触发 panic 的通用的错误处理函数,在最顶层的 unmarshal l函数中可恢复该 panic,该函数将检查 panic 类型,并在其是“local panic”时将其作为错误返回...我发现他们实际上是危险的救急: ? 以上的检查错误一直令人痛苦,这种模式忽略了写入时的序列错误,而是在写完时才提示。 因此,任何执行的操作都会在执行完错误后执行。 如果这些比分片更昂贵呢?...= nil 将不会成功。 那么我们应该如何以安全的方式编写测试? 我们必须对接口值和非零值都进行 nil-check,检查接口对象指向的值...使用反射! ? 错误或功能?
以上说的这几个语言用各自的方式表示了 null,但都没有解决所谓的「十亿美金错误」,所谓「十亿美金错误」的本质在于语言的粗糙设计导致类型声明不诚实。...不一定,它可能返回一个 null,这就导致每一次使用的时候都要小心翼翼地对其进行判断,否则很有可能就会在运行的时候发生错误,这是一个非常糟糕的事情。...另外,在 Kotlin 中,这种技术还被更广泛地应用在一般的类型处理上,比如你可以对对象进行类型判定,并在不同的分支里将该对象作为不同类型的对象使用,不需要额外的显式类型转换,这被称为 Smart Cast...它们使用参数化的类型来表示 null 这个概念。例如在 Scala 中,有一个 Option[T] 8 类型,对于一个可能为空的对象,不将其类型设置为 T 而是设置为 Option[T]。...协变、逆变与不变 一文中谈过,Java 无法在参数化类型声明的时候指定其在其类型参数上的型变类型,相对于 Scala 中直观的写法,为了使用 Optional,在 Java 中我们必须要这样写: Optional
这常常是因为string的不变性使得其行为类似于值类型(见下一点)。实际上,它更多地表现为一个普通的引用类型。请查看我的参数传递和内存二文,以参阅关于值类型和引用类型之间差异的更多细节。...string类型是特殊的(译者注:指资源占用不固定),因为其对象本身的大小不同。据我所知,相似行为的其他类型只有数组。...文化与国际化的遗产 Unicode的一些奇怪特性导致字符串和字符处理中的怪异。许多字符串方法是文化性敏感的——换句话说,它们的作用取决于当前线程的文化。...不幸的是,由于两个空格间的原始字符串中的“奇怪”字符,转换将失败。IndexOf匹配双重空格,忽略额外的角色,但Replace并没有。...我的猜测是,因为这样的“尴尬”数据,将导致很多的代码的运行失败(我暂时也不会声称我的所有代码都是免疫的)。 微软有一些关于字符串处理的建议——它们可以追溯到2005年,但仍然值得一读。
在后文中我们会描述分布数据集上支持的操作。 并行集合的一个重要参数是将数据集划分成分片的数量。对每一个分片,Spark会在集群中运行一个对应的任务。...可写类型支持 PySpark序列文件支持利用Java作为中介载入一个键值对RDD,将可写类型转化成Java的基本类型,然后使用Pyrolite将java结果对象串行化。...向Spark传递函数 Spark的API严重依赖于向驱动程序传递函数作为参数。有三种推荐的方法来传递函数作为参数。...Spark还会在shuffle操作(比如reduceByKey)中自动储存中间数据,即使用户没有调用persist。这是为了防止在shuffle过程中某个节点出错而导致的全盘重算。...如果累加器在对RDD的操作中被更新了,它们的值只会在启动操作中作为RDD计算过程中的一部分被更新。所以,在一个懒惰的转化操作中调用累加器的更新,并没法保证会被及时运行。
---- crash发生在objc_storeStrong函数中,猜测是ARC(自动引用计数)下导致的问题,尝试将process_blackhole方法的参数类型修改为void *或id __unsafe_unretained...通过汇编单步调试发现上述crash属于访存错误,objc_retain调用传入了一个堆栈上的地址。这很奇怪,按理说传入的应当是该方法的实参对象——一个堆中的地址,指向一个合法对象。...在本文初步分析 部分有提到,ARC环境下,在方法函数体的实现部分之前,编译器会对参数调用objc_storeStrong以持有传入的参数,存放在栈中 说明 可以看到,模拟器下参数传递正确,而真机下却很奇怪地传递了参数的地址而非本身...说明 这次ARM64架构的传参更加奇怪,传递的分别是第二个参数以及第一个参数的地址 测试代码3 为了结合正确情况的代码分析,编写测试代码Code 4-4,该代码根据函数的实际类型定义了指针,经测试真机和模拟器都能正常执行...两边传参约定的不对称,导致被调方法获取到了错误的参数,引起了crash。如下图所示。 ? 值得注意的是,在正确使用不定参数的情况下不会发生这个问题,会负责处理平台相关的问题。
Twirl 采用Scala作为底层模板语言,所以你无需学习额外的语法便可以轻松上手。...大家可能觉得奇怪,没有了上下文,在模板中如何获取当前的请求呢?答案很简单:通过参数传递喽!利用Scala的隐式参数的特性,在调用模板函数时不需要显示传入,编译器会自动传入。...message 错误消息提示或错误消息对应的key。 args 用于填充错误消息的参数。 Form.globalErrors包含在Form.errors中,其key值为空,无对应的表单项。...//绑定成功 Ok(Json.obj("status" -> 0)) } ) 页面渲染 我们可以直接将 Form 对象作为模板参数传递到模板层,Play 专门为模板层提供了一个工具包(views.html.helper...除了上文的 formWithErrors 对象, 我们也可以将业务数据填充到 Form 实例中,然后传递给模板页面进行渲染: val userForm = Form(tuple("email" ->
另外 Mongo Scala Driver 的数据库操作默认返回 Observable 类型,如果你忘记了调用 toFuture 方法,或是没有消费返回数据,则数据库操作实际上并不会被执行,在开发中很容易引入一些...另外 Play Mongo 不会过多关注底层驱动的实现细节,而是将关注点放在与 Play Framework 的集成上,可以为开发者提供更舒适的开发体验。...} 由于这些隐式的 Format 对象是在模型层的包对象(package object)中创建的,所以使用时无需显式导入,编译器会自动加载。...这意味着查询操作将会在 common-user collection 上执行, 并且返回的结果类型是 User。 需要注意的是,在该方式下无法改变返回的结果类型。...我们仍然可以通过改变第2个参数类型从而改变返回的结果类型。
这个规则有一个例外,编译器也会在类的伙伴对象定义中查找所需的 implicit 定义。...如果在调用方法时没有提供某个参数,编译器会查找当前作用域是否有符合条件的 implicit 对象作为参数传入(有点类似 dependency injection )。...但在报错之前,编译器会搜寻是否定义了从 Double 到 Int 的隐含类型转换。在本例中,它找到了一个 doubleToInt 。...x y z demo演示出了隐式转换如何用他们”装扮”现在库 隐式转换操作规则 隐式定义是指编译器为了修改类型错误而允许插入到程序中的定义....eg.如果尝试传递 Dollar 对象给入参为 Euro的方法,源类型是 Dollar, 而目标类型是Euro.
然后是面向对象编程,知道如何执行对象上的操作,以及如何与相互交流,从而完成任务。 相比之下,函数式编程将一个程序作为数学函数来评估,以生成一个结果值。...为了使函数能够方便传递数据,并且从其他函数中,函数编程通常作为一个集合,以最可能的方式定义数据结构。它们还允许函数间传递,就像它们是数据参数一样。...· 简洁:在函数语言中,数据通过通用集合数据类型从嵌套函数隐式传递到其父函数。...随之,Scala 的设计者做出了几个重要决定,将 Scala 定位为函数编程到主流的突破性语言。 · Scala 代码在 Java 虚拟机(JVM)中运行。...· Scala 在语法上和 Java 相似,并且像 Java 一样,在编译时执行类型检查而不是在运行时,从而消除了由类型不兼容而导致运行错误的可能性。
空值 我将 1965 年创建的空值引用(null reference)称为“亿万美元错误”。当时,我正设计首个完全类型系统,用于面向对象语言中的引用。...异常和空值一样,会破坏类型系统。 如果将异常作为错误处理的首选方式,那么就无法获知函数是返回了期望值,还是发生了故障。抛出异常的函数也无法实现复合(Compose)。...React 中,函数参数 props 是不可变的;而 TypeScript 中,没有内置提供适用的不可变数据结构支持。...重申 Linux Torvalds 的观点: C++ 是一种很糟的(面向对象)语言……将项目局限于 C,意味着整个项目不会因为任何愚蠢的 C++“对象模型”而搞砸。...使用 this 关键字通常会导致一些细微而奇怪的错误,难以调试。 并发 JavaScript 使用事件循环支持单线程并发,无需考虑加锁等线程同步机制。
考虑到 Scala 是静态类型的,我可以享受到诸多静态类型的好处,诸如将文档作为类型, IDE 代码自动完成,动态代码重构( deterministic refactoring )以及执行速度等...但 Scala 还让我以简洁和类型安全的方式获得某些通常是动态语言的好处,例如在已有类上增加新方法的能力,或者将类型传递给没有共同继承关系的方法。 Scala 是怎样改变了我对编程的看法的呢?...exists 方法在对象集合中迭代,并依次将每个元素传递给函数对象。在这里, name 字符串被视为字符集合,因此 exists 会把字符串的每一个字符都传递给该函数。...另外需要注意的一点不同是命令式例子中潜在的偏移错误,因为你必须显式地指出迭代的上标。在函数化的版本里这种错误不会产生,在这种方式下,函数化版本相对而言不易出错。...通常将输入值称做函数的参数,将输出值称做函数的值。
下面的这张图解释了我们可以在 Root 组件通过 provide 来注入数据,在 DeepChild 组件中通过 Inject 来注入对应的 key,就可以将数据顺利的从 Root 传递到 DeepChild...对象(后面会说),参数 2 可以是任意类型的数据包括响应式的对象: 在下面的代码中提供了 message 为 key,text 为内容的数据给后代组件: <script setup lang="ts"...inject() 函数来传入指定数据的 key 来得到 Root 组件中的响应式 text,而且这个响应式对象不会被解包,得到的数据对象依然保持着响应式链接。...上面的例子我们就直接传递的响应式的 text 对象,那在 Root 组件的后代组件中每一个都有可能会对这个响应式的数据做更改,为了保证更改函数的统一管理,Vue 建议我们在定义将响应式数据的变更与 provide...: Symbol 作为一个出场率极低的对象在这就派上它的用场,我们在使用 provide 向后代组件提供数据的时候 key 一定的不能重复了,这个场景与 Symbol 对象的特点是完美契合的,虽然我们可以将所以的
领取专属 10元无门槛券
手把手带您无忧上云