对Scala新手的一个隐含问题似乎是:编译器在哪里寻找隐含?我的意思是隐含的,因为这个问题似乎永远不会完全形成,好像没有它的话.:-)例如,integral
下面的值来自哪里?
scala> import scala.math._
import scala.math._
scala> def foo[T](t: T)(implicit integral: Integral[T]) {println(integral)}
foo: [T](t: T)(implicit integral: scala.math.Integral[T])Unit
scala> foo(0)
scala.math.Numeric$IntIsIntegral$@3dbea611
scala> foo(0L)
scala.math.Numeric$LongIsIntegral$@48c610af
Run Code Online (Sandbox Code Playgroud)
对于那些决定学习第一个问题的答案的人来说,另一个问题是,在某些明显模糊的情况下(但无论如何编译),编译器如何选择使用哪个隐式?
例如,scala.Predef
定义两个转换String
:一个转换为WrappedString
另一个转换为StringOps
.然而,这两个类都有很多方法,所以为什么Scala不会在调用时抱怨歧义map
?
注意:这个问题的灵感来自另一个问题,希望以更一般的方式陈述问题.该示例是从那里复制的,因为它在答案中被引用.
我正在进行一些练习,并得到一个警告:
隐式转换失去整数精度'NSUInteger'(又名'unsigned long')到'int'
我很喜欢这个菜鸟,非常感谢任何帮助..谢谢.
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[])
{
@autoreleasepool {
NSArray *myColors;
int i;
int count;
myColors = @[@"Red", @"Green", @"Blue", @"Yellow"];
count = myColors.count; // <<< issue warning here
for (i = 0; i < count; i++)
NSLog (@"Element %i = %@", i, [myColors objectAtIndex: i]);
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么第一个和第二个写入工作但不是最后一个?有没有办法我可以允许所有3个并检测它是1,(int)1还是我传入?真的为什么一个允许但最后一个?第二个被允许但不是最后一个真的让我大吃一惊.
using System;
class Program
{
public static void Write(short v) { }
static void Main(string[] args)
{
Write(1);//ok
Write((int)1);//ok
int i=1;
Write(i);//error!?
}
}
Run Code Online (Sandbox Code Playgroud) 我最近发现这个代码:
public static implicit operator XElement(XmlBase xmlBase)
{
return xmlBase.Xml;
}
Run Code Online (Sandbox Code Playgroud)
什么static implicit operator
意思?
是否可以在c#中定义枚举的隐式转换?
可以实现这一目标的东西?
public enum MyEnum
{
one = 1, two = 2
}
MyEnum number = MyEnum.one;
long i = number;
Run Code Online (Sandbox Code Playgroud)
如果没有,为什么不呢?
为了进一步讨论和提出这个想法,我跟进了我目前处理这个问题的方法:改进C#enum
以下代码如何工作?
typedef char (&yes)[1];
typedef char (&no)[2];
template <typename B, typename D>
struct Host
{
operator B*() const;
operator D*();
};
template <typename B, typename D>
struct is_base_of
{
template <typename T>
static yes check(D*, T);
static no check(B*, int);
static const bool value = sizeof(check(Host<B,D>(), int())) == sizeof(yes);
};
//Test sample
class Base {};
class Derived : private Base {};
//Expression is true.
int test[is_base_of<Base,Derived>::value && !is_base_of<Derived,Base>::value];
Run Code Online (Sandbox Code Playgroud)
请注意,这B
是私人基地.这是如何运作的?
注意operator B*()
是const.它为什么如此重要?
为什么template<typename T> static yes …
在Scala中,我们可以使用至少两种方法来改进现有或新类型.假设我们想要表达某些东西可以使用a来量化Int
.我们可以定义以下特征.
trait Quantifiable{ def quantify: Int }
Run Code Online (Sandbox Code Playgroud)
然后我们可以使用隐式转换来量化例如字符串和列表.
implicit def string2quant(s: String) = new Quantifiable{
def quantify = s.size
}
implicit def list2quantifiable[A](l: List[A]) = new Quantifiable{
val quantify = l.size
}
Run Code Online (Sandbox Code Playgroud)
导入这些后,我们可以quantify
在字符串和列表上调用该方法.请注意,可量化列表存储其长度,因此它可以避免在后续调用时对列表进行昂贵的遍历quantify
.
另一种方法是定义一个"证据" Quantified[A]
,表明某种类型A
可以量化.
trait Quantified[A] { def quantify(a: A): Int }
Run Code Online (Sandbox Code Playgroud)
然后,我们提供这种类型的类的实例为String
和List
地方.
implicit val stringQuantifiable = new Quantified[String] {
def quantify(s: String) = s.size
}
Run Code Online (Sandbox Code Playgroud)
如果我们编写一个需要量化其参数的方法,我们写道:
def sumQuantities[A](as: List[A])(implicit ev: Quantified[A]) =
as.map(ev.quantify).sum …
Run Code Online (Sandbox Code Playgroud) 该声明
printf("%f\n",0.0f);
Run Code Online (Sandbox Code Playgroud)
打印0.
但是,声明
printf("%f\n",0);
Run Code Online (Sandbox Code Playgroud)
打印随机值.
我意识到我表现出某种未定义的行为,但我无法弄明白为什么具体.
所有位都为0的浮点值仍然有效float
,值为0.
float
并且int
在我的机器上具有相同的大小(如果它甚至相关).
为什么使用整数文字而不是浮点文字printf
会导致此行为?
如果我使用PS,可以看到相同的行为
int i = 0;
printf("%f\n", i);
Run Code Online (Sandbox Code Playgroud) 值一千字:
#include<string>
#include<iostream>
class SayWhat {
public:
SayWhat& operator[](const std::string& s) {
std::cout<<"here\n"; // To make sure we fail on function entry
std::cout<<s<<"\n";
return *this;
}
};
int main() {
SayWhat ohNo;
// ohNo[1]; // Does not compile. Logic prevails.
ohNo[0]; // you didn't! this compiles.
return 0;
}
Run Code Online (Sandbox Code Playgroud)
将数字0传递给接受字符串的方括号运算符时,编译器不会抱怨。相反,它会在输入以下方法之前编译并失败:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Run Code Online (Sandbox Code Playgroud)
以供参考:
> g++ -std=c++17 -O3 -Wall -Werror -pedantic test.cpp -o test && ./test
> g++ --version
gcc …
Run Code Online (Sandbox Code Playgroud) 例如:
operator bool() const
{
return col != 0;
}
Run Code Online (Sandbox Code Playgroud)
col
是一个int.operator bool() const
工作怎么样?
c++ ×4
c# ×3
operators ×2
scala ×2
c ×1
coding-style ×1
enums ×1
implicit ×1
implicits ×1
int ×1
objective-c ×1
overloading ×1
printf ×1
std ×1
string ×1
templates ×1
type-traits ×1