有没有办法使这项工作(Scala 2.8.1):
class A
class B
def f(implicit b: B) {}
implicit val a = new A
implicit def aToB(a: A) = new B
f(a) // works ok
f // error: could not find implicit value for parameter b: B
Run Code Online (Sandbox Code Playgroud)
其实我的问题是与Lift的(2.2)的依赖注入,我试图给供应商[T]转换为T和隐含需要它在类的构造函数,而不每一VAL之后增加进口:
object DependencyFactory extends Factory {
implicit def vendorToVal[T](vendor: Vendor[T]): T = vendor.vend
implicit val db = new FactoryMaker[DbAccess](Model) {}
//uncommenting the following line makes it work, but can we avoid it?
//import db._
implicit val userStore = new FactoryMaker[UserStore](new …Run Code Online (Sandbox Code Playgroud) 鉴于这个例子:
Animal thisIsACat = new Cat();
有没有从隐式转换Cat到Animal?
为了澄清:
假设:
class Animal
{
}
class Cat: Animal
{
}
Run Code Online (Sandbox Code Playgroud) 编辑
好了,@ Drexin提出了一个很好的重点:使用隐式转换器时类型安全性/惊人结果的丢失.
不太常见的转换怎么样,与PreDef冲突的冲突不会发生?例如,我正在使用Scala中的JodaTime(伟大的项目!).在我的implicits定义的同一个控制器包对象中,我有一个类型别名:
type JodaTime = org.joda.time.DateTime
Run Code Online (Sandbox Code Playgroud)
以及将JodaTime转换为Long的隐式(对于在ScalaQuery之上构建的DAL,其中日期存储为Long)
implicit def joda2Long(d: JodaTime) = d.getMillis
Run Code Online (Sandbox Code Playgroud)
这里PreDef和我的控制器包含义之间不存在歧义,并且控制器含义不会过滤到DAL,因为它在不同的包范围内.所以,当我这样做
dao.getHeadlines(articleType, Some(jodaDate))
Run Code Online (Sandbox Code Playgroud)
对我,IMO,安全地进行了对Long的隐式转换,并且鉴于基于日期的查询被大量使用,我节省了一些样板.
类似地,对于str2Int转换,控制器层接收servlet URI参数作为String - > String.在许多情况下,URI然后包含数字字符串,所以当我过滤路由以确定String是否是Int时,我不想每次都使用stringVal.toInt; 相反,如果正则表达式通过,让我隐式将字符串值转换为Int.总之它看起来像:
implicit def str2Int(s: String) = s.toInt
get( """/([0-9]+)""".r ) {
show(captures(0)) // captures(0) is String
}
def show(id: Int) = {...}
Run Code Online (Sandbox Code Playgroud)
在上面的上下文中,这些用于隐式转换的有效用例,还是更多,总是明确的?如果是后者,那么什么是有效的隐式转换用例?
ORIGINAL
在一个包对象中,我定义了一些隐式转换,其中一个是Int的简单String:
implicit def str2Int(s: String) = s.toInt
Run Code Online (Sandbox Code Playgroud)
通常这样工作正常,采用Int param但接收String的方法转换为Int,返回类型设置为Int的方法也是如此,但实际返回的值是String.
很好,现在在某些情况下,编译器错误与可怕的模糊隐含:
对象中的方法augmentString类型为(x:String)的predef scala.collection.immutable.StringOps和方法str2Int(s:String)Int是可能的转换函数,从java.lang.String到?{val toInt:?}
我知道这种情况发生的情况是在尝试手动内联String-to-Int转换时.例如,val i = "10".toInt
我的解决方法/ hack一直在创建一个asInt帮助器以及包对象中的implicits:def asInt(i: Int) = i并用作,asInt("10")
那么,隐含的隐含最佳实践(即通过烧毁来学习),还是有一些指导方针可以遵循,以免陷入自己制造的陷阱?换句话说,应该避免简单,常见的隐式转换,并且只使用转换类型唯一的地方吗?(即永远不会遇到模棱两可的陷阱) …
我将试着用一个例子来解释我的问题:
class V<T>
{
public readonly Func<T> Get;
public readonly bool IsConstant;
V(Func<T> get, bool isConstant)
{
Get = get;
IsConstant = isConstant;
}
public static implicit operator V<T>(T value)
{
return new V<T>(() => value, true);
}
public static implicit operator V<T>(Func<T> getter)
{
return new V<T>(getter, false);
}
}
void DoSomething<T>(V<T> v)
{
//...
}
void Main()
{
DoSomething<string>("test"); // (1) type inference is not working
DoSomething<string>((V<string>)(() => "test")); // (2) implicit operator does not work
}
Run Code Online (Sandbox Code Playgroud)
在方法中 …
我有一个类用于保存从配置文件加载的值.为了使这个类更容易使用,我已经为一些基本类型设置了许多隐式转换.
我想要转换为的类型之一是IEnumerable(T).例如,如果程序员在配置文件中有这样的值
a = "1,2,3,4"
Run Code Online (Sandbox Code Playgroud)
在C#代码中,他可以写
IEnumerable<int> a = Config.a;
Run Code Online (Sandbox Code Playgroud)
理想情况下,我想写的是这个
public static implicit operator IEnumerable<T>(ConfigurationValue val)
{
string value = val;
string[] parts = value.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
List<T> convertedTypes = new List<T>();
foreach (string part in parts)
{
T converted = Convert.ChangeType(part.Trim(), typeof(T));
convertedTypes.Add(converted);
}
return convertedTypes;
}
Run Code Online (Sandbox Code Playgroud)
但这给了我语法错误,T未定义.有没有办法定义这样的转换或是否有特殊的语法?
另外,对于记录,我在.Net Framework 4.0中使用C#4.0
对于给定Map的常数
val ctt = Map("a" -> 1, "b" -> 2)
Run Code Online (Sandbox Code Playgroud)
如何定义String插值器c在哪里
c"a"
Run Code Online (Sandbox Code Playgroud)
交付List(1)?
注意已经考虑过字符串插值但仍不清楚如何继续.
更新
c"a,b"
res: List(1,2)
c" a, b "
res: List(1,2)
c"a,w"
res: List(1)
c"w"
res: List()
Run Code Online (Sandbox Code Playgroud) C++ 11 std::function应该实现operator bool() const,为什么clang告诉我没有可行的转换?
#include <functional>
#include <cstdio>
inline double the_answer()
{ return 42.0; }
int main()
{
std::function<double()> f;
bool yes = (f = the_answer);
if (yes) printf("The answer is %.2f\n",f());
}
Run Code Online (Sandbox Code Playgroud)
编译错误是:
function_bool.cpp:12:7: error: no viable conversion from 'std::function<double ()>' to 'bool'
bool yes = (f = the_answer);
^ ~~~~~~~~~~~~~~~~
1 error generated.
Run Code Online (Sandbox Code Playgroud)
编辑我没有看到explicit关键字..没有隐式转换然后,我想我将不得不使用static_cast.
以下来自我的C++书籍的引文:
当我们使用直接初始化时,我们要求编译器使用普通函数匹配来选择与我们提供的参数最匹配的构造函数.当我们使用复制初始化时,我们要求编译器将右侧操作数复制到正在创建的对象中,必要时转换该操作数.
对我来说,这个粗体位会产生一些模糊性.它使得听起来像右手操作数被转换为类类型,然后使用复制构造函数,例如;
string s = "hello";
Run Code Online (Sandbox Code Playgroud)
会成为...
string s = string("hello");
Run Code Online (Sandbox Code Playgroud)
它使用复制构造函数.如果这是真的那么我的测试程序;
#include <iostream>
using namespace std;
class A{
public:
A(const A& b): data(b.data) { cout << "The first way" << endl;}
A(const char* c): data(c) { cout << "The second way" << endl;}
string data;
};
int main(){
A first("hello");
A second = "sup";
}
Run Code Online (Sandbox Code Playgroud)
应该产生"第二种方式,第二种方式,第一种方式".然而它反而打印出"第二种方式,第二种方式".从这里我可以得出结论它是使用const char*构造函数而不是复制构造函数.我会好的,除非后来说......
在复制初始化期间,允许编译器(但没有义务)跳过复制/移动构造函数并直接创建对象.也就是说,允许编译器重写
Run Code Online (Sandbox Code Playgroud)string null_book = "9-999-99999-9";成
Run Code Online (Sandbox Code Playgroud)string null_book("9-999-99999-9");但是,即使编译器省略了对复制/移动构造函数的调用,复制/移动构造函数也必须存在,并且必须在程序中的该点可访问(例如,非私有).
我不确定为什么复制构造函数甚至需要在这些示例中提及,否则
string null_book = "9-999-99999-9"
Run Code Online (Sandbox Code Playgroud)
总是隐含地意味着仍然使用const char*构造函数?实际上,我不需要定义复制构造函数以使上述工作正常.但是,如果我将"const A&"构造函数设置为私有(其他公共),那么我的程序将无法运行.为什么必须为不涉及它的隐式转换定义复制构造函数?什么构造函数"string null_book …
c++ copy-constructor implicit-conversion copy-initialization copy-elision
我有一些特殊的数字类.该类可以用双构造:
struct FancyDouble{
FancyDouble& operator = (double v){
this->value = v;
return *this;
}
};
FancyDouble myFancyDouble = 5.0;
Run Code Online (Sandbox Code Playgroud)
类从提供了一种(隐含的)转换double到FancyDouble.有没有办法做相反的事情?所以当我FancyDouble在数字表达式中使用a 时,我想写:
double a = 123;
double b = b * myFancyDouble;
Run Code Online (Sandbox Code Playgroud)
我查看了参考文献,我认为这是不可能的,但我不是很确定.
如何distanceTo(..)使用std::size_tas参数更改签名以使编译器在调用时发出警告或错误?
class Point {
private:
float value;
public:
Point(float value) : value(value){};
float distanceTo(const Point &point) { return point.value - value; }
};
int main() {
std::size_t index = 1;
Point start(1);
Point end(4);
float dist = start.distanceTo(index); // compiles, but should not!
std::cout << dist;
return 0;
}
Run Code Online (Sandbox Code Playgroud) c++ ×4
c# ×3
scala ×3
.net ×2
generics ×2
c#-4.0 ×1
c++11 ×1
class ×1
conflict ×1
constructor ×1
copy-elision ×1
ienumerable ×1
lift ×1
string ×1