我有一个隐式参数定义为:
的类 class Test(implicit one: String)
我想像这样实例化那个对象:
val grr = new Test("aha")
我收到以下异常。
error: too many arguments for constructor Test: ()(implicit one: String)Test
val grr = new Test("aha")
但如果我这样称呼它
val grr = new Test()("haha")
grr: Test = Test@3bd40a57
我得到一个Test对象。
为什么Scala实例化隐式方法要求您在此实例中使用空参数调用对象?为什么会为这样的对象实例提供隐式空白参数列表?
答案 0 :(得分:5)
首先,Test
不是一个隐式类。有关隐式类的讨论,请参阅this。
相反,Test
是一个没有显式构造函数参数但只有一个implicit String
参数的类。这意味着你可以实例化Test
的唯一方法就是像你一样明确地提供隐式参数,这是尴尬和失败的目的,或者在{{1}中只提供一个String
在实例化时的范围,并让编译器"拿起它。"
换句话说,如果你在范围内有类似的东西:
implicit
然后你需要做的就是实例化implicit val s: String = "haha"
:
Test
如果你没有范围,编译器会告诉你。这是一件好事。
主要的是要确保你区分隐式参数和隐式类。
答案 1 :(得分:0)
隐式空白参数列表仅适用于构造函数,而不适用于所有方法。我想这可能是因为解析器需要区分对Test类型(或伴随对象)的引用和对构造函数的引用。如果它允许没有参数的构造函数,那么Test本身就不明确了。
通常在scala中,当你引用“隐式类”时,你会这样做:
lock = threading.Lock()
total_mem= 1024 * 1024 * 500 #500MB spare memory
@contextlib.contextmanager
def ensure_memory(size):
global total_mem
while 1:
with lock:
if total_mem > size:
total_mem-= size
break
time.sleep(1) #or something else...
yield
with lock:
total_mem += size
def _load_root(url):
...
r = requests.get(url, timeout=(settings.ENGINE_SCRAPER_REQUEST_TIMEOUT + i, 10 + i), verify=False, stream=True) #add the stream=True to make request wait on on loading the entire request
...
with ensure_memory(r.headers['content-length']):
#now do stuff here :)
html = r.content
...
return {'success': True, 'root': root}
然后你可以这样做:
object Container {
implicit class Test(val one: string)
}
它将隐式地将字符串转换为Test对象。