我有这个代码:
enum Enum: String {
case A = "A"
}
let s: String? = Enum(rawValue: "A")
Run Code Online (Sandbox Code Playgroud)
当然,它不编译.通常,我这样解决它:
let s: String? = Enum(rawValue: "A")?.rawValue
Run Code Online (Sandbox Code Playgroud)
但是,Xcode说我应该添加.map { $0.rawValue }:
这很奇怪,因为很明显,Xcode意识到访问rawValue可以Enum变成一个String.但为什么建议使用map?为什么不直接访问它?
我以为Xcode会这样思考:
我在左边有一个字符串常量和一个原始值为字符串的枚举.类型不兼容,但我知道
rawValue可以将枚举转换为字符串.我只是建议用户添加?.rawValue!
什么是Xcode背后的"思考过程"?
PS我的目的是检查"A"枚举是否是有效的原始值.如果是,则将其分配给s,否则分配nil.我知道这不太实用,但我只关心Xcode的行为.
在Java中,Optional是作为public final class Optional<T> { ... }和不作为的密封层次Some和None.
为什么这不是这种情况?这是sealedJava 缺席的解决方法吗?背后有更深层次的推理吗?
如果您看一下方法实现,您会看到通过这种方式它具有丑陋的空检查:
public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent())
return empty();
else {
return Optional.ofNullable(mapper.apply(value));
}
}
Run Code Online (Sandbox Code Playgroud)
它们不仅丑陋,而且如果你有一个更长的方法链,isPresent则需要在每次调用时进行评估,即使Optional从一开始就是空的.
如果我们可以通过链中传递固定的实现,则可以避免.
optional
.map(i -> i) // isPresent()
.map(Object::toString) // isPresent()
.map(String::length) // isPresent()
.map(...) // isPresent()
Run Code Online (Sandbox Code Playgroud)
为什么没有用于模拟空和非空案例的子类型?
我并没有特别问为什么 Optional是最终的,而是为什么它没有实现,Some和None许多其他语言一样,所以为什么可选的声明为最终类并不是真的有用.
在我目前的工作中,我们将一些代码重写为Java 8.如果你有这样的代码:
if(getApi() != null && getApi().getUser() != null
&& getApi().getUser().getCurrentTask() != null)
{
getApi().getUser().getCurrentTask().pause();
}
Run Code Online (Sandbox Code Playgroud)
你可以简单地重写它
Optional.ofNullable(this.getApi())
.map(Api::getUser)
.map(User::getCurrentTask)
.ifPresent(Task::pause);
Run Code Online (Sandbox Code Playgroud)
不改变代码行为.但是,如果中间的东西可以抛出NPE,因为它没有被检查为空呢?
例如:
if(getApi() != null && getApi().getUser() != null
&& getApi().hasTasks())
{
getApi().getMasterUser(getApi().getUser()) //<- npe can be here
.getCurrentTask().pause();
}
Run Code Online (Sandbox Code Playgroud)
使用optionals重写这样的代码的最佳方法是什么?(它应该完全相同,并在getMasterUser(...)返回null 时抛出npe )
UPD 第二个例子:
if(getApi()!=null && getApi.getUser() != null)
{
if(getApi().getUser().getDepartment().getBoss() != null)// <- nre if department is null
{
getApi().getUser().getDepartment().getBoss().somefunc();
}
}
Run Code Online (Sandbox Code Playgroud)
它有api,用户,老板的零检查,但不是部门.怎么用选项?
我发现这个问题应该对我有所帮助,但是那里的解决方案对我不起作用,而且我不确定某些事情是否发生了变化,或者问题是否与我的代码有关.
let messageBody = "hello"
let urlSafeBody = messageBody.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLHostAllowedCharacterSet())
print("URLSAFEBODY: \(urlSafeBody)")
WKExtension.sharedExtension().openSystemURL(NSURL(string: "sms:&body=\(urlSafeBody)")!)
Run Code Online (Sandbox Code Playgroud)
执行此代码时,我收到的消息是,urlSafeBody在nil时强制解包可选,导致崩溃.为什么是urlSafeBody零?我知道我强行打开它,但我不明白为什么在明确指定之后它永远是零.
关于参考类型应该做什么optional和variant应该做什么一直存在争论,特别是在转让方面.我想更好地理解围绕这个问题的辩论.
optional<T&> opt;
opt = i;
opt = j; // should this rebind or do i=j?
Run Code Online (Sandbox Code Playgroud)
目前,如果任何类型是参考类型,那么决定是使形式optional<T&>不正确并variant::operator=形成格式错误 - 回避论证并仍然给我们大部分功能.
那是什么的争论opt = j 应该重新绑定相关参考?换句话说,我们为什么要这样实现optional:
template <class T>
struct optional<T&> {
T* ptr = nullptr;
optional& operator=(T& rhs) {
ptr = &rhs;
return *this;
}
};
Run Code Online (Sandbox Code Playgroud) 我经常需要为函数使用可选类型:
std::optional<int32_t> get(const std::string& field)
{
auto it = map.find(field);
if (it != map.end()) return it->second;
return {};
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在一行中返回可选值?例如:
std::optional<int32_t> get(const std::string& field)
{
auto it = map.find(field);
return it != map.end() ? it->second : {};
}
Run Code Online (Sandbox Code Playgroud)
导致错误
error: expected primary-expression before '{' token
return it != map.end() ? it->second : {};
^
Run Code Online (Sandbox Code Playgroud) (可能不是C++ 14,可能是库TS)工具make_optional被定义为(在n3672中):
template <class T>
constexpr optional<typename decay<T>::type> make_optional(T&& v) {
return optional<typename decay<T>::type>(std::forward<T>(v));
}
Run Code Online (Sandbox Code Playgroud)
为什么有必要改变类型T(即不仅仅是返回optional<T>),是否有一种哲学(以及实际)理由用于decay转换?
该java.util.Objects类被延长了一些新的方法
分别
对象#requireNonNullElseGet() in Java-9.
如果第一个参数为非null,则它们将返回第一个参数,否则返回非null的第二个参数或者supplier.get()的非null值
jshell> String nullStr = null;
nullStr ==> null
jshell> Objects.requireNonNullElse(nullStr,"lorem ipsum");
$13 ==> "lorem ipsum"
jshell> Objects.requireNonNullElseGet(nullStr,() -> "lorem ipsum");
$14 ==> "lorem ipsum"
Run Code Online (Sandbox Code Playgroud)
但是新功能与Optional#orElse和Optional#orElseGetOptional类中已存在的功能重叠
jshell> Optional.ofNullable(nullStr).orElse("lorem ipsum");
$17 ==> "lorem ipsum"
jshell> Optional.ofNullable(nullStr).orElseGet(() -> "lorem ipsum");
$18 ==> "lorem ipsum"
Run Code Online (Sandbox Code Playgroud)
新方法Objects和相应Optional方法之间的唯一区别是供应商的第二个参数或值必须为非null否则Objects抛出NPE:
jshell> Objects.requireNonNullElseGet(nullStr,() -> null);
| java.lang.NullPointerException thrown: supplier.get()
| at Objects.requireNonNull (Objects.java:246)
| at Objects.requireNonNullElseGet …Run Code Online (Sandbox Code Playgroud) 在我看来,在C++中可以使用该类型std::optional<std::reference_wrapper<T>>.这种类型的对象本质上是对类型对象T或空值的引用,即几乎是一个指针.我的问题:
有没有之间的任何概念上的差异std::optional<std::reference_wrapper<T>>和T*?
有什么实际区别吗?是否有可能选择std::optional<std::reference_wrapper<T>>结束的情况T*?
我有一个关于Java 8的Optional的问题,其目的是解决NullPointerException异常问题.
问题是,让两种类型让我们选择的原因是什么:
Optional.of(T value) <-----non-null value, null value will throw NPE
Optional.ofNullable(T value) <----- nullable value
Run Code Online (Sandbox Code Playgroud)
因为我的期望是,当我使用时:
Optional.of(nullValue);
Run Code Online (Sandbox Code Playgroud)
它不会抛出一个NullPointerException.
一些回复后扩大了我的问题:
为什么人们会选择Optional而不是普通if-else的null检查?