是否可以从可选项中获取对象类型?
例如,如果我有一个具有可选字符串属性的类,我可以以某种方式返回字符串类型吗?
我拥有的确切用例是我有许多自定义类,所有自定义类都有一个属性,它将另一个自定义类存储为可选值。我想编写一个泛型函数,它将创建存储在optional。
中的对象类的实例这是我正在寻找的一个例子,虽然.dynamicType不起作用,因为它是可选的:
a = Categorization.where(category_id: @category_id)
答案 0 :(得分:1)
您只需要检查是否存在可选项:
func myFunc(c: Class2) -> Class1? {
if let c1 = c.myOp{
return c1.dynamicType()
}
return nil
}
OR
func myFunc(c: Class2) -> Class1? {
if c.myOp != nil{
return c.myOp!.dynamicType()
}
return nil
}
请注意,您的返回类型也必须是可选的。
答案 1 :(得分:1)
因为你想在Generics中使用它,我试过你。它有效,但它可能没那么有用。
首先进行一些设置:
这是一个辅助协议,用于确保我们的Generic类型具有已知的init方法。
protocol ZeroParameterInit {
init()
}
这是从可选项中获取类型的扩展名:
extension Optional {
var dynamicWrappedType : Wrapped.Type {
return Wrapped.self
}
}
在您的代码中实施:
class Class1 : ZeroParameterInit {
required init() {}
}
class Class2 {
var myOp: Class1?
}
var c = Class2()
c.myOp = c.myOp.dynamicWrappedType.init()
通用实施:
class Class1 : ZeroParameterInit {
required init() {}
}
class Class2<T where T : ZeroParameterInit> {
var attribute: Optional<T>// used long syntax to remind you of : Optional<Wrapped>
init(attr:T) {
attribute = attr
attribute = nil
}
}
创建实例的功能:
func myFunc<T>(instance: Class2<T>) -> T {
return instance.attribute.dynamicWrappedType.init()
}
一些测试:
let alpha = Class1()
let beta = Class2(attr: alpha)
beta.attribute = myFunc(beta)
问题:
您无法在不通知其类型的通用属性的情况下创建Class2
的实例。所以你需要传递一些对象/类型,这会使事情再次复杂化。
一些可能改善其运作方式的额外方法:
init() {
}
let delta = Class2<Class1>()
delta.attribute = myFunc(delta)
init(type:T.Type) {
}
let epsilon = Class2(type: Class1.self)
epsilon.attribute = myFunc(epsilon)
答案 2 :(得分:0)
在模拟器中尝试过,如果我理解你,似乎做正确的事情
@BasePathAwareController
@RequestMapping("/users")
public class RestApiController implements ResourceProcessor<Resource<User>>{
@Autowired
private EntityLinks entityLinks;
@RequestMapping(method=RequestMethod.POST)
@ResponseBody
public ResponseEntity<Resource<User>> saveUser(@Param("name") String name) {
// Testing
System.out.println(name);
Resource<User> resource = new Resource<>(new User());
return new ResponseEntity<>(resource , HttpStatus.OK);
}
@Override
public Resource<User> process(Resource<User> resource) {
LinkBuilder lb = entityLinks.linkFor(User.class);
resource.add(new Link(lb.toString()));
return resource;
}
}