当我的程序包含两个文件时:
main.c中
#include <stdio.h>
int main(void) {
printf("%lf\n",f());
return 0;
}
Run Code Online (Sandbox Code Playgroud)
func.c
double f(int a) {
return 1;
}
Run Code Online (Sandbox Code Playgroud)
编译器不显示任何错误.
当我的程序只包含一个文件时:
main.c中
#include <stdio.h>
int main(void) {
printf("%lf\n",f());
return 0;
}
double f(int a) {
return 1;
}
Run Code Online (Sandbox Code Playgroud)
Visual C++ 2008编译器显示以下错误:
Error 2 error C2371: 'f' : redefinition; different basic types d:\temp\projects\function1\function1\1.c 8 function1
Run Code Online (Sandbox Code Playgroud)
任何人都能解释这种奇怪的行为吗?
如果我定义一个简单的stringToInt函数并将其存储为val,那么一切都按预期工作,例如
scala> def stringToInt1: (String => Int) = _.toInt
stringToInt1: String => Int
scala> stringToInt1("1")
res0: Int = 1
Run Code Online (Sandbox Code Playgroud)
但是,如果我然后隐藏它,它会导致堆栈溢出:
scala> implicit def stringToInt2: (String => Int) = _.toInt
stringToInt2: String => Int
scala> stringToInt2("1")
java.lang.StackOverflowError
at .stringToInt2(<console>:7)
at $anonfun$stringToInt2$1.apply(<console>:7)
at $anonfun$stringToInt2$1.apply(<console>:7)
...
Run Code Online (Sandbox Code Playgroud)
起初我怀疑这是因为下划线没有解决我的预期,但情况并非如此,因为这种隐式val的样式适用于以下简单函数:
scala> implicit def plusTwo: (Int => Int) = _ + 2
plusTwo: Int => Int
scala> plusTwo(2)
res2: Int = 4
Run Code Online (Sandbox Code Playgroud)
如果我显式定义参数,没有堆栈溢出:
scala> implicit def stringToInt3(s: String) = s.toInt
stringToInt3: (s: String)Int
scala> stringToInt3("1")
res3: Int …Run Code Online (Sandbox Code Playgroud) 给出一些方法
def f[A,B](p: A)(implicit a: X[A,B], b: Y[B])
Run Code Online (Sandbox Code Playgroud)
隐式参数列表中的abefore 的顺序b对类型推断是否重要?
我认为只有不同参数列表中的参数放置很重要,例如类型信息仅从左到右通过参数列表流动.
我问,因为我注意到在单隐式列表中更改隐式参数的顺序使得我的程序编译.
以下代码使用:
这是一个简单的sbt构建文件,以帮助编译示例:
scalaVersion := "2.11.5"
libraryDependencies += "com.chuusai" %% "shapeless" % "2.1.0"
scalaSource in Compile := baseDirectory.value
Run Code Online (Sandbox Code Playgroud)
在这个例子上.此代码编译:
import shapeless._
import shapeless.ops.hlist.Comapped
class Foo {
trait NN
trait Node[X] extends NN
object Computation {
def foo[LN <: HList, N <: HList, TupN <: Product, FunDT]
(dependencies: TupN)
(computation: FunDT)
(implicit tupToHlist: Generic.Aux[TupN, LN], unwrap: Comapped.Aux[LN, Node, N]) = ???
// (implicit …Run Code Online (Sandbox Code Playgroud) 在下面的例子中,有没有办法避免隐式分辨率选择defaultInstance并使用intInstance而不是?代码后的更多背景:
// the following part is an external fixed API
trait TypeCls[A] {
def foo: String
}
object TypeCls {
def foo[A](implicit x: TypeCls[A]) = x.foo
implicit def defaultInstance[A]: TypeCls[A] = new TypeCls[A] {
def foo = "default"
}
implicit val intInstance: TypeCls[Int] = new TypeCls[Int] {
def foo = "integer"
}
}
trait FooM {
type A
def foo: String = implicitly[TypeCls[A]].foo
}
// end of external fixed API
class FooP[A:TypeCls] { // with type …Run Code Online (Sandbox Code Playgroud) 简短问题:
有没有办法让scala编译器告诉我程序中给定点使用的某个隐式声明在哪里?
如果没有,是否可以手动遵循一种算法来找出隐式声明的位置?
长问题:
我正在遵循简单的Spray Crud 教程。
在下面的代码片段中(作为教程的此仓库):
pathEnd {
post {
entity(as[Question]) { question =>
completeWithLocationHeader(
resourceId = questionService.createQuestion(question),
ifDefinedStatus = 201, ifEmptyStatus = 409)
}
}
} ~
Run Code Online (Sandbox Code Playgroud)
as接受一个隐式类型FromRequestUnmarshaller[T](此处为完整资料):
def as[T](implicit um: FromRequestUnmarshaller[T]) = um
Run Code Online (Sandbox Code Playgroud)
当我问IntelliJ时,这个隐式是从哪里来的(使用CMD + SHIFT + P),我得到:
当我遵循第一个提示时,我得到了:
trait UnmarshallerLifting {
implicit def fromRequestUnmarshaller[T](implicit um: FromMessageUnmarshaller[T]): FromRequestUnmarshaller[T] =
new FromRequestUnmarshaller[T] {
def apply(request: HttpRequest): Deserialized[T] = um(request)
}
...
Run Code Online (Sandbox Code Playgroud)
这并不能帮助我确定隐式FromRequestUnmarshaller[T]函数的来源,因为如果我检查类层次结构,就无法确定特征是如何UnmarshallerLifting混合的QuestionResource …
鉴于以下路线
val route1: PathMatcher[Unit] = PathMatcher("app")
val route2: PathMatcher1[String] = PathMatchers.Segment
val route3: PathMatcher[Unit] = PathMatcher("lastSegment")
Run Code Online (Sandbox Code Playgroud)
我可以轻松定义
val resultingRoute: PathMatcher[Tuple1[String]] = route1 / route2 / route3
Run Code Online (Sandbox Code Playgroud)
获得预期的类型(PathMatcher [Tuple [String]]).
但是以编程方式创建路线
val routeDef = List(route1, route2, route3)
val resultingRoute = routeDef.reduce((a,b) => a / b)
Run Code Online (Sandbox Code Playgroud)
不会编译,给我
找不到参数连接的隐含值:akka.http.scaladsl.server.util.TupleOps.Join [_1,_1]
此外,推断出的resultRoute类型是
PathMatcher[_ >: Unit with Tuple1[String] with join.Out]
Run Code Online (Sandbox Code Playgroud)
我真的很感激有任何提示给我一些迹象,说明我在这里做错了什么,或者如何解决这个问题.
为了完整性,这是我的导入:
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.{PathMatcher, _}
Run Code Online (Sandbox Code Playgroud)
非常感谢!
我有一个类似的课程
case class A(a: Int, b: String)
Run Code Online (Sandbox Code Playgroud)
和一个功能
def f(a: Int)(implicit b: String) =???
Run Code Online (Sandbox Code Playgroud)
可以这样做吗?
val a = A(11, "hello")
a match {
case A(a, implicit b) => f(a)
}
Run Code Online (Sandbox Code Playgroud)
如何在不提取后明确声明参数的情况下隐藏参数b.
Scala允许使用type关键字定义类型,这些类型通常具有不同的含义和目的,具体取决于声明的时间。
如果type在一个对象或一个包对象内部使用,则应定义一个类型别名,即另一种类型的简称/简称:
package object whatever {
type IntPredicate = Int => Boolean
def checkZero(p: IntPredicate): Boolean = p(0)
}
Run Code Online (Sandbox Code Playgroud)
在类/特征中声明的类型通常打算在子类/子特征中被覆盖,并且最终也被解析为具体类型:
trait FixtureSpec {
type FixtureType
def initFixture(f: FixtureType) = ...
}
trait SomeSpec extends FixtureSpec {
override type FixtureType = String
def test(): Unit = {
initFixture("hello")
...
}
}
Run Code Online (Sandbox Code Playgroud)
抽象类型声明还有其他用途,但无论如何最终它们都会解析为某些具体类型。
但是,还有一个选项可以在对象内部声明抽象类型(即,没有实际定义):
object Example {
type X
}
Run Code Online (Sandbox Code Playgroud)
与例如抽象方法相反,它可以编译:
object Example {
def method: String // compilation error
}
Run Code Online (Sandbox Code Playgroud)
由于无法扩展对象,因此永远无法将它们解析为具体类型。
我认为这样的类型定义可以方便地用作幻像类型。例如(使用Shapeless的标记类型):
import …Run Code Online (Sandbox Code Playgroud) 当我尝试通过隐式类为该类创建扩展并重载现有的通用方法时,它会因编译错误而失败:
error: overloaded method value getAs with alternatives:
(fieldName: String)String <and>
(i: Int)String
cannot be applied to (FooField.type)
r.getAs[String](FooField)
Run Code Online (Sandbox Code Playgroud)
通过隐式重载正常(非泛型)方法时,效果很好。在Scala 2.12.10上试用。链接到scastie。我想念什么?代码:
trait Row {
// Two overloads for `getAs[T]`
def getAs[T](i: Int): T
def getAs[T](fieldName: String): T
// Two overloads for `get`
def get(i: Int): String
def get(fieldName: String): String
}
trait Field {
def columnName: String
def columnDescription: String
}
case object FooField extends Field {
def columnName: String = "Foo"
def columnDescription: String = "Foo desc" …Run Code Online (Sandbox Code Playgroud) implicit ×10
scala ×8
akka ×1
akka-http ×1
c ×1
c# ×1
declaration ×1
explicit ×1
function ×1
generics ×1
operators ×1
scala-2.10 ×1
spray ×1
type-members ×1
types ×1