Scala高阶函数参数疑问:是否为传名参数?通配符为何可选?
Let's walk through each of your questions clearly, using the code you provided as reference:
1. Is the author's claim about "by-name parameters" correct?
Nope, that's a mistake.
The parameter f: Double => Double in your higher-order function is a function type parameter, not a Scala by-name parameter.
By-name parameters in Scala use the syntax f: => Double—they represent an expression that takes no arguments and returns a Double, and they're evaluated lazily (only when used inside the function). Your f is a function that accepts a Double and returns a Double, which is a regular pass-by-value parameter (you're passing a function instance as a value).
2. What would a pass-by-value parameter look like here?
Actually, your current f parameter is already pass-by-value! When you call totalCostWithDiscountFunctionParameter, the function you pass (whether it's applyDiscount(_) or applyDiscountValueFunction) is evaluated to a function instance first, then passed to f.
If you're asking about a non-function pass-by-value parameter, that would be something like f: Double (but that would make this no longer a higher-order function). Given the context, though, you're referring to function-type pass-by-value parameters, which is exactly what Double => Double is—you pass a concrete function instance as the value.
3. Are by-name parameters called that because of lazy loading?
Exactly! The core feature of Scala's by-name parameters is lazy/late evaluation: the parameter expression isn't computed when you call the function. Instead, it's re-computed every time you reference the parameter inside the function body.
Just to clarify again: your f parameter isn't a by-name parameter. It's a regular function value passed by value—the function instance is fixed when you call the higher-order function, no lazy evaluation involved here.
4. Why use a wildcard when passing the def function applyDiscount, but not the val function applyDiscountValueFunction? And why do both work without the wildcard?
This all comes down to Scala's Eta Expansion:
applyDiscountis adefmethod, not a function value. WritingapplyDiscount(_)is an explicit way to convert this method into a function of typeDouble => Double.applyDiscountValueFunctionis already avalbound to a function value (its type isDouble => Double), so you can pass it directly without any conversion.
As for why it works without the wildcard? Scala automatically does eta expansion when the context expects a function type and you pass a method with a matching signature. For example, if you write:
totalCostWithDiscountFunctionParameter("Glazed Donut")(5)(applyDiscount)
the compiler automatically expands it to (x: Double) => applyDiscount(x)—exactly the same as writing applyDiscount(_).
Quick Code Example to Show Equivalence
All three of these calls behave identically:
// Explicit eta expansion with wildcard totalCostWithDiscountFunctionParameter("Glazed Donut")(5)(applyDiscount(_)) // Automatic eta expansion of def method totalCostWithDiscountFunctionParameter("Glazed Donut")(5)(applyDiscount) // Direct pass of pre-defined function value totalCostWithDiscountFunctionParameter("Glazed Donut")(5)(applyDiscountValueFunction)
内容的提问来源于stack exchange,提问作者Jwan622

