Der Code Snippet, das Sie angegeben haben, ist keine Blockdeklaration: es ist eine Blockdeklaration und eine Blockdefinition. Zuerst erklären Sie eine Kennung aBlock
genannt:
int (^aBlock)(BOOL)
dann definieren Sie einen Block:
^(BOOL param) { ...
Beide werden analysiert und getrennt ausgewertet. Da Sie dem anderen einen zuweisen, führt der Compiler eine Typüberprüfung durch, um sicherzustellen, dass der Ausdruck auf der linken Seite (Ihre aBlock
Deklaration) vom selben Typ ist wie der Ausdruck auf der rechten Seite (die Blockdefinition). .
Also, die Antwort ist, diese Teile müssen separat ausgewertet werden. Da die Blockdefinition selbst kompiliert wird, müssen Sie den Typ param
angeben, da der Compiler sonst nicht weiß, um welchen Typ es sich handelt. (Ja, Sie könnten in diesem Fall eine Ausnahme machen und über die Zuweisung schauen, aber überall sonst in der C-Sprache deklarieren Sie zuerst einen Typ, also warum anders?)
Aber - Sie können sagen - , wenn das stimmt, warum musste ich nicht den Rückgabetyp (int
) auf der rechten Seite definieren?
Sehr scharf von Ihnen. Die Antwort besteht darin, dass Sie beim Schreiben eines Blockausdrucks den Rückgabetyp nicht definieren müssen, da der Compiler dies aus der return-Anweisung (oder einem Mangel davon) innerhalb des Blocks ableiten kann.
(Warum müssen Sie Rückgabetypen mit Funktionsdefinitionen enthalten? Nun, Geschichte, denke ich. Programmiersprache Definitionen von unvollkommenen Menschen geschaffen wurden.)
Ja, das ist großartig, danke. Nur um zu verdeutlichen, ist Ihr zweites Stück Code ein Beispiel für die Übertragung von Tippinformationen (und daher verpönt)? – chm
Nein, ich zeige nur, dass die Typen zwischen der linken und der rechten Seite unterschiedlich sein können und der Code kompiliert und ausgeführt wird. Es gibt nicht viel Typ-Überprüfung mit anderen Blöcken als Rückgabetypen, soweit ich das beurteilen kann. Es gibt keine Übertragung von Tippinformationen, da das nicht wirklich eine Sache ist. Ich habe das ein bisschen komisch formuliert, ich habe versucht zu sagen, dass selbst wenn der Compiler so etwas tun würde, es nicht unbedingt korrekt wäre, wie es ist einige polymorphe Eigenschaften von Blöcken, die ein solches Merkmal stören würde. –