Understanding Scala method overloading, optional/default parameters for an API client lib
I'm trying to write a Scala client library for PrestaShop's Web Service and I'm having some trouble coming up with clean/user-friendly method definitions. Basically, I don't have a good enough understanding of Scala metho开发者_开发百科d overloading, optional/default method parameters etc to get it right.
Problem 1
Using the PrestaShop API you can delete one resource ID or a set of IDs, so I tried setting up a pair of methods using type-based overloading:
def delete(resource: String, id: Int) {
deleteURL(apiURL + resource + "/" + id)
}
// But this second definition overrides the first!
def delete(resource: String, ids: Array[Int]) {
deleteURL(apiURL + resource + "/?id=[%s]".format(ids.mkString(",")))
}
Clearly I don't understand type-based overloading. Should I just give the methods different names (deleteID, deleteIDs), or is there another way of doing this?
Problem 2
With the PrestaShop API you can 'head' one resource by specifying an ID, or head all resources of one type by leaving the resource ID out. Additionally you can refine the head by passing in parameters like "filter"="xxx". So I tried to come up with some optional parameters like this:
def head(resource: String, id: Option[Int] = None,
params: Option[Map[String, String]]): String = {
headURL(
apiURL + resource +
(if (id.isDefined) "/" + id.get else "") + "?" +
(if (params.isDefined) canonicalize(validate(params.get)) else "")
)
}
Is this approach to using Options[] correct? As I understand it, it means that the user would need to pass in e.g. Some(23) to provide an id of 23 to the head method, rather than just passing in 23. Is there a better way of doing this?
Many thanks for any help you can give me coming up with a better API client!
Problem 1:
Was this in the REPL you tried it out? Seems to be a REPL thing:
Welcome to Scala version 2.9.0.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.6.0_24).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def delete(resource : String, id : Int) = 1
delete: (resource: String, id: Int)Int
scala> def delete(resource : String, ids : Array[Int]) = 2
delete: (resource: String, ids: Array[Int])Int
scala> delete("foo", 1)
<console>:9: error: type mismatch;
found : Int(1)
required: Array[Int]
delete("foo", 1)
^
In a compiled file it works nice:
def delete(resource : String, id : Int) = 1
def delete(resource : String, ids : Array[Int]) = 2
val x = delete("id", 1)
val y = delete("id", Array(1, 2))
No errors…
Problem 2:
Why not? I wouldn't say it's a typical use case for an Option though. You could just extra methods:
def head(resource: String, id: Int, params: Option[Map[String, String]]) =
head(resource, Some(id), params)
def head(resource: String, params: Option[Map[String, String]]) =
head(resource, None, params)
and make the one you have private. I guess it depends…
On problem 1, I'm not really sure what the problem is.
It looks like you've overloaded delete
just fine there. You can invoke the first method with something like delete("a resource", 1)
, or the second with delete("a resource", Array(1, 2, 3))
.
Note that overriding isn't the same thing as overloading. Overriding is when you define a method with the same signature (same name, parameter types, return type) as one you inherit from another class or trait. Overloading is when you make different methods that have the same name but have different parameters (which I guess is what's relevant for this problem).
精彩评论