以下是代码:
import scala.collection.mutable
/**
* Created by IDEA on 25/10/15.
*/
class HttpRequest(builder: Builder) {
val headers: Map[String, String]
var body: String
var path: String
class Builder {innerBuilder =>
private val headers = new mutable.HashMap[String, String]()
private var body: String = _
private var path: String = _
def addHeader(name: String, value: String): Unit = {
headers.put(name, value)
innerBuilder
}
def body(b: String): Builder = {
body = b
innerBuilder
}
def path(p: String) = {
path = p
innerBuilder
}
def build: HttpRequest = {
new HttpRequest(innerBuilder)
}
}
}
我有两个错误:
Error:(27, 7) overloaded method path needs result type
path = p
^
Error:(32, 23) type mismatch;
found : HttpRequest.this.Builder
required: Builder
new HttpRequest(innerBuilder)
^
我做错了什么?
BTW,我试图将这个java文件翻译成scala:
/***
* Excerpted from "Functional Programming Patterns",
* published by The Pragmatic Bookshelf.
* Copyrights apply to this code. It may not be used to create training material,
* courses, books, articles, and the like. Contact us if you are in doubt.
* We make no guarantees that this code is fit for any purpose.
* Visit http://www.pragmaticprogrammer.com/titles/mbfpp for more book information.
***/
package com.mblinn.oo.tinyweb;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
public class HttpRequest {
private Map<String, String> headers;
private String body;
private String path;
public Map<String, String> getHeaders() {
return headers;
}
public String getBody() {
return body;
}
public String getPath() {
return path;
}
private HttpRequest(Builder builder) {
this.headers = Collections.unmodifiableMap(builder.headers);
this.body = builder.body;
this.path = builder.path;
}
public static class Builder {
private Map<String, String> headers;
private String body;
private String path;
private Builder() {
headers = new HashMap<String, String>();
}
public Builder addHeader(String name, String value) {
headers.put(name, value);
return this;
}
public Builder body(String body) {
this.body = body;
return this;
}
public Builder path(String path) {
this.path = path;
return this;
}
public HttpRequest build() {
return new HttpRequest(this);
}
public static Builder newBuilder() {
return new Builder();
}
public static Builder builderFrom(HttpRequest request) {
Builder builder = new Builder();
builder.path(request.getPath());
builder.body(request.getBody());
Map<String, String> headers = request.getHeaders();
for (String headerName : headers.keySet())
builder.addHeader(headerName,
headers.get(headerName));
return builder;
}
}
}
import scala.collection.mutable.Map
/**
* Created by IDEA on 25/10/15.
*/
class HttpRequest(builder: Builder) {
val headers: Map[String, String] = Map.empty
var body: String = _
var path: String = _
import scala.collection.mutable
class Builder {
private val headers = new mutable.HashMap[String, String]()
private var body: String = _
private var path: String = _
def addHeader(name: String, value: String): this.type = {
headers.put(name, value)
this
}
def body(b: String): this.type = {
body = b
this
}
def path(p: String): this.type = {
path = p
this
}
// def build: HttpRequest = {
// new HttpRequest(this)
// }
}
}
还有两个问题:
似乎不允许在外部类的构造中引用内部类(intellij无法解析它)
new HttpRequest(this)
报告类型不匹配。
答案 0 :(得分:4)
你提到的其余两点的问题是Builder
是HttpRequest
的内部类(事实上,正如所写的那样,它是{的每个特定实例的单独定义的内部类。 {1}}!),因此需要以HttpRequest
类型的方式解决。但要正确地完成这项工作,您需要将Builder的定义移动到HttpRequest.Builder
的伴随对象中。类似的东西:
HttpRequest
这里有几点说明:
case class HttpRequest(headers: Map[String, String], body: String, path: String)
object HttpRequest {
def apply(builder: HttpRequest.Builder): HttpRequest =
HttpRequest(Map(builder.headers.toSeq: _*),
builder.body,
builder.path)
class Builder {
private[HttpRequest] val headers = new mutable.HashMap[String, String]()
private[HttpRequest] var body: String = _
private[HttpRequest] var path: String = _
def addHeader(name: String, value: String): Builder = {
headers.put(name, value)
this
}
def body(b: String): Builder = {
body = b
this
}
def path(p: String): Builder = {
this.path = p
this
}
def build: HttpRequest = {
HttpRequest(this)
}
}
def builderFrom(request: HttpRequest): Builder = {
val builder = new Builder().path(request.path).body(request.body)
request.headers.foldLeft(builder){ (b,h) => b.addHeader(h._1, h._2) }
}
}
类现在位于伴随对象中(可以被认为是Java中标记为“静态”的所有内容的持有者,尽管它不仅仅是这样,特别是对于案例类)。Builder
方法的地方,buildFrom
方法通过链接方法调用和请求标题的折叠构建Builder
。因为折叠产生Builder
作为结果,所以这将是buildFrom
方法的返回值。private[HttpRequest]
字段上的Builder
访问修饰符可确保这些字段仅在HttpRequest
类中可见,其中包含内部Builder
类(需要它们以便它们可以可以使用apply
方法访问。