问题
This issue appeared when I was answering this question. It should be some stupid error I am doing, but I can't get what error it is…
myMatrix = [22 33; 44 55]
Returns:
>> subsref(myMatrix, struct('type','()','subs',{{[1 2]}} ) );
ans =
22 44
While using it with cells:
myCell = {2 3; 4 5}
Returns:
>> subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) );
ans =
2 % WHATTT?? Shouldn't this be 2 and 4 Matlab??
Checking the subsref
documentation, we see:
See how MATLAB calls subsref for the expression:
A{1:2} The syntax A{1:2} calls B = subsref(A,S) where S.type='{}' and S.subs={[1 2]}.
This seems not to be true because the returned value by subsref is just the first argument, not all arguments.
Then if one does:
>> [a,b]=subsref(myCell,struct('type','{}','subs',{{[1 2]}} ) )
a =
2
b =
4 % Surprise!
But this is not the same as myCell{[2 4]} which will automatically return:
>> myCell{[1 2]}
ans =
2
ans =
4
I would need to use subsref with one output for every index I use access myCell
, or am I missing something?
回答1:
When the curly braces ({}
) are used for indexing a cell array, the output is a comma-separated list. This implicitly calls subsref but the behavior is slightly different from invoking it directly.
subsref by itself is a technically a function, and the comma-separated list returned by the curly braces simply behaves like varargout in this case. This means that you should specify an appropriate "sink" for all desired output results, just like you would do with any other function returning multiple parameters, otherwise they would be ignored.
回答2:
dont ask me why, this is just something I tried:
myOutput=subsref(myCell,struct('type','()','subs',{{[1 2]}} ) )
note the 'type','()'!
this gives me:
myOutput =
[2] [4]
with myOutput as cell. Converting back:
>> myOutput=cell2mat(subsref(myCell,struct('type','()','subs',{{[1 2]}})))
myOutput =
2 4
This is just a "fast" answer, that will need some improvements or some background-info as well...
回答3:
I was further investigating @EitanH answer and managed to find more details.
Yeah, it returns a comma separed list, but the function subsref
should return a comma separed list just the A{:}
does. Here is an example where the functions behave different, but this is an expected behavior, I would like the class .get
method to return a list and one class common function to behave as common functions getting only the first argument from the cell.
classdef ListReturn
properties(Access = private)
a
end
properties(Dependent)
getA
end
methods
function self = ListReturn(a)
self.a = a;
end
function varargout = get.getA(self)
varargout = {self.a};
end
function varargout = getAFcn(self)
varargout = {self.a};
end
end
end
There is a substantial difference when calling the functions, exactly as the .get:
k=[ListReturn(2) ListReturn(3) ListReturn(4) ListReturn(5)]
>> k.getAFcn
ans =
2
>> k.getA
ans =
2
ans =
3
ans =
4
ans =
5
So it seems that using A{1:2}
or A{:}
works like a Cell.get()
, whereas the subsref
works as a common matlab function, returning only one argument when the output arguments are not specified, as one function in C,java,C++
would do. Anyway, I just feel like subsref
should work as the .get
.
来源:https://stackoverflow.com/questions/18384735/subsref-with-cells